Zend session and zend auth - zend-framework

I have made a login system through zend auth here is the code
// userAuthentication
public function authAction(){
$request = $this->getRequest();
$registry = Zend_Registry::getInstance();
$auth = Zend_Auth::getInstance();
$DB = $registry['DB'];
$authAdapter = new Zend_Auth_Adapter_DbTable($DB);
$authAdapter->setTableName('user')
->setIdentityColumn('user_name')
->setCredentialColumn('user_password');
$username = $request->getParam('username');
$password = $request->getParam('password');
$authAdapter->setIdentity($username);
$authAdapter->setCredential($password);
$result = $auth->authenticate($authAdapter);
if($result->isValid()){
$data = $authAdapter->getResultRowObject(null,'password');
$auth->getStorage()->write($data);
$this->_redirect('/login/controlpannel');
}else{
$this->_redirect('/login/login');
}
}
This work fine now. There is user_id (column) in user (table) where there are username and password too. I need to get that specific user_id from this table which just login and put it in session through
$user_session = new Zend_Session_Namespace('user_session');
$user_session->username = $username;
$user_id->user_id = $user_id;
so that I can query some info against this $user_id and pass the result into view (name) controlpanel

Get user id from storage :
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
echo $userInfo->user_id;

While this was already answered, I tend to use the getIdentity() function more frequently than the getStorage()->read() chain. Examples below.
// to check if authenticated
Zend_Auth::getInstance()->hasIdentity();
// to actually get the details from storage
Zend_Auth::getInstance()->getIdentity()->user_id;
// if I need to use the identity over and over
$identity = Zend_Auth::getInstance()->getIdentity();
$userId = $identity->user_id;

You can access the data the way Teez suggest or just pull it from Zend_Session_Namespace.
15.1.3.1. Default Persistence in the PHP Session By default, Zend_Auth provides persistent storage of the identity from a successful
authentication attempt using the PHP session. Upon a successful
authentication attempt, Zend_Auth::authenticate() stores the identity
from the authentication result into persistent storage. Unless
configured otherwise, Zend_Auth uses a storage class named
Zend_Auth_Storage_Session, which, in turn, uses Zend_Session. A custom
class may instead be used by providing an object that implements
Zend_Auth_Storage_Interface to Zend_Auth::setStorage().
Zend_Auth_Storage_Session uses a session namespace of 'Zend_Auth'.
This namespace may be overridden by passing a different value to the
constructor of Zend_Auth_Storage_Session, and this value is internally
passed along to the constructor of Zend_Session_Namespace. This should
occur before authentication is attempted, since
Zend_Auth::authenticate() performs the automatic storage of the
identity.

assigning an array to a session, you must provide a name to the session you area creating, i.e. you must do setStorage before you do getStorage.
you must write your code like this:
// userAuthentication
public function authAction(){
$request = $this->getRequest();
$registry = Zend_Registry::getInstance();
$auth = Zend_Auth::getInstance();
$DB = $registry['DB'];
$authAdapter = new Zend_Auth_Adapter_DbTable($DB);
$authAdapter->setTableName('user')
->setIdentityColumn('user_name')
->setCredentialColumn('user_password');
$username = $request->getParam('username');
$password = $request->getParam('password');
$authAdapter->setIdentity($username);
$authAdapter->setCredential($password);
$authAdapter->setStorage(new Zend_Auth_Storage_Session('User_Auth'));
$result = $auth->authenticate($authAdapter);
if($result->isValid()){
$data = $authAdapter->getResultRowObject(null,'password');
$auth->getStorage()->write($data);
$this->_redirect('/login/controlpannel');
}else{
$this->_redirect('/login/login');
}
}
and then to get your storage value, you must use this:
$x = new Zend_Auth_Storage_Session('User_Auth');
$y = $x->read();
and you get everything in $y as an object.
Enjoy!

This is my approach and it s working nice:
1-i start by defining an init function in the bootstrap
protected function _initSession()
{
$UserSession = new Zend_Session_Namespace('UserSession');
$UserSession->setExpirationSeconds(/* you may fix a limit */);
Zend_Registry::set('UserSession', $UserSession);
}
/* in the Login action,after correct username & pwd */
// Create session
$UserSession = Zend_Registry::get('UserSession');
// Get the user from database
$db = Zend_Db_Table::getDefaultAdapter();
$user = $db->fetchRow("SELECT * FROM user_table WHERE user_email = '".$user_email."'");
//then you assign to $user to $UserSession variable :
$UserSession->user = $user;
//finaly don't forget to unset session variable in the Logout action ...

user = Zend_Auth::getInstance()->getIdentity();
if(!#$this->user){
$objSession->errorMsg = " Please Login First .. ! ";
$this->_redirect('/user/login');
}
?>

Related

Symfony 2.1 Autologin after facebook login

I'm creating an intranet, therefore all users have account automatically created for them. They then go to a url to create their password. All that works great. I'm now trying to allow them to "attach" their Facebook account to their user account. This is where my troubles have started...
I've successfully gotten the user to authenticate properly after a facebook login with this
method in SecurityController
public function loginCheckFacebookAction()
{
$request = $this->getRequest();
$session = $request->getSession();
$response = new Response();
$sessionUser = $this->getUser();
$facebook = $this->get('facebook');
$fbUser = $facebook->getUser(); // facebook id
if ($fbUser) {
try {
$em = $this->getDoctrine()->getManager();
$repo = $em->getRepository("IntranetBundle:User");
$user = $repo->findUserByFBID($fbUser);
if($user){
$targetPath = $session->get("_target_path");
$firewall = "secured_area";
$roles = $user->getRoles();
$rolesArray = array();
foreach($roles as $role):
$rolesArray[] = $role->getRole();
endforeach;
$token = new UsernamePasswordToken($user, $user->getPassword(), $firewall, $rolesArray);
$event = new InteractiveLoginEvent($this->getRequest(), $token);
$this->get("event_dispatcher")->dispatch("security.interactive_login", $event);
$this->get('security.context')->setToken($token);
/*
If I uncomment out either of the following redirects
the redirect happens but the user is not authenticated properly
If I comment them out I'm just rendering my error template. The user
however, is authenticated properly.
*/
if(isset($targetPath)){
//return $this->redirect($targetPath);
} else {
//return $this->redirect($this->generateUrl("ssla_intranet_homepage"));
}
}
} catch (FacebookApiException $e) {
$user = null;
}
// I just render this template to be able to view debug bar.
//User is authenticated properly.
$pageParameters = $this->getPageParameters();
$pageParameters["page"] = "error";
$pageParameters["error"] = array();
$pageParameters["error"]["message"] = "Something went wrong with authentication";
return $this->render('IntranetBundle:Error:index.html.twig', $pageParameters);
}
Do I need to register a listener for all interactive_login events that then handles all post-login redirection rather than trying to redirect within the same method?
First project using Symfony, and this is killing me. Any thoughts?
By the way, I've looked into the FOSFacebookBundle, but wanted to be able to authenticate with a number of different methods, including doctrine, gmail, facebook, and twitter.

In Zend authentication how do i check additional column along with authentication?

I have a scenario where i need to check some additional columns while doing the authentication. This is because, the application stores some usernames in database and some in LDAP. the authentication precedence is for usernames in database. If username exist in database, we will not check in LDAP else we will check it in LDAP.
For LDAP users, we are keeping a copy of there usernames in same "user" table with a blank password column. To disgusting both group of users, there is an additional column called userDirectory with values "LDAP and INTERNAL". we have to keep a copy of LDAP usernames for application specific settings and all.
Also username+userDirectory is a uniqueKey
Now my problem is, sometimes there will be multiple users with same username but in different userDirectory. as mentioned above LDAP users will not have a password stored in database and that authentication is a separate code snippet.
I am using the below code for DB authentication. Even though i am adding a condition setCredentialTreatment('md5(?) AND userDirectory="internal"'), it is searching LDAP users also. HOW do i restrict this for userDirectory='internal'
$dbAdapter = Zend_Db_Table::getDefaultAdapter();
$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
$authAdapter->setTableName('users')
->setIdentityColumn('username')
->setCredentialColumn('password')
->setCredentialTreatment('md5(?) AND userDirectory="internal"');
$authAdapter->setIdentity($username);
$authAdapter->setCredential($password);
I have changed your code:
$dbAdapter = Zend_Db_Table::getDefaultAdapter();
$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
$authAdapter->setTableName('users')
->setIdentityColumn('username')
->setCredentialColumn('password')
->setCredentialTreatment('MD5(?)'); // changed
$authAdapter->setIdentity($username);
$authAdapter->setCredential($password);
$authAdapter->getDbSelect()->where('userDirectory = "internal"'); // added
http://framework.zend.com/manual/1.12/en/zend.auth.adapter.dbtable.html
check the last code under Advanced Usage By Example, code is as follows
$registry = Zend_Registry::getInstance();
$DB = $registry['DB'];
$authAdapter = new Zend_Auth_Adapter_DbTable($DB,'usertable','username','password');
$authAdapter->setIdentity($request->getParam('username'));
$authAdapter->setCredential($request->getParam('password'));
$select = $authAdapter->getDbSelect();
$select->where('`active` = 1');
$result = $authAdapter->authenticate();
if($result->isValid()){
//set user proper to zend instance
$this->_redirect('/index');
}
else
{
//logout or redirect to same page
}
Extends Zend_Auth_Adapter_DbTable and override _authenticateCreateSelect() method like this
protected function _authenticateCreateSelect()
{
$select = parent::_authenticateCreateSelect();
return $select->where('userDirectory = ?','internal');
}

Zend Authentication and Login - accepts foo and foo1! both for a saved foo password

I'm trying to script an authentication and login script and am quiet there.. I have a password 'password' saved in my database... it works with the password 'password' however should not work with 'password1!' or prefix or suffix two characters more.... IT shouldn't accept it... but if I enter something different (different string, or a few more characters), it gives me a proper error...
That is the only row in my database table... there are no duplicate entries..
Following is the code
public function validate_login($valuethrown) {
$username = $valuethrown['username'];
$email = $valuethrown['email'];
$password = $valuethrown['password'];
echo "Values thrown to the model are : $username, $email, $password";
$authAdapter = $this->getAuthAdaptor();
$authAdapter->setIdentity($email)
->setCredential(md5($password));
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($authAdapter);
if ($result->isValid()) {
$data = $authAdapter->getResultRowObject(null,'password');
$auth->getStorage()->write($data);
$this->_redirect('home');
} else {
echo "</br>Wrong Password</br>";
}
//check login details
}
public function getAuthAdaptor() {
$authAdapter = new Zend_Auth_Adapter_DbTable(Zend_Db_Table::getDefaultAdapter());
$authAdapter->setTableName('users')
->setIdentityColumn('email')
->setCredentialColumn('password');
return $authAdapter;
}
HELP!!!!

How do I pass _SESSION('userName') from this Zend_Auth method to the layout?

I'm having a difficult time understanding how Zend_Session_Namespace is integrated with Zend_Auth. I have this method I'm using as the action to Authenticate my login page-it is working correctly and redirecting to the /monthly view:
public function authAction(){
$request = $this->getRequest();
$registry = Zend_Registry::getInstance();
$auth = Zend_Auth::getInstance();
$DB = $registry['DB'];
$authAdapter = new Zend_Auth_Adapter_DbTable($DB);
$authAdapter->setTableName('users')
->setIdentityColumn('UserName')
->setCredentialColumn('Password');
// Set the input credential values
$uname = $request->getParam('UserName');
$paswd = $request->getParam('Password');
$authAdapter->setIdentity($uname);
$authAdapter->setCredential($paswd);
// Perform the authentication query, saving the result
$result = $auth->authenticate($authAdapter);
// TRYING TO SET THE NAMESPACE
$this->session = new Zend_Session_Namspace('UserName');
if($result->isValid()){
$data = $authAdapter->getResultRowObject(null,'password');
$auth->getStorage()->write($data);
$this->_redirect('/monthly');
}else{
$this->_redirect('/login');
}
}
But I need to be able to store UserName as a Zend_session and call it from monthly controller. I'm not doing things right because I just get a blank screen when I try and do this:
public function indexAction()
{
$this->view->userName = Zend_Session_Namespace('UserName');
}
With the lines:
$data = $authAdapter->getResultRowObject(null,'password');
$auth->getStorage()->write($data);
You're writing all the user's information, except the password, which is OK. Where ever you need to access the logged in user's details, you can do something like (updated as per your comment):
public function indexAction() {
$auth = Zend_Auth::getInstance();
if($auth->hasIdentity()) {
$userData = $auth->getIdentity();
$this->view->user = $userData;
}
}
in the view file (index.phtml) just: echo $this->user->firstname
That's it. If one day you decide to change the storage for Zend_Auth from session, to, for example, database, this piece of code will still work.
Youre not useing the correct namespace. Zend_Auth use the Zend_Auth namespace. The namespace is the structure, not the key for a value. so your session looks something like this:
Array('Zend_Auth' => array ('UserName' => 'myname')
Well thats not accurate exactly because you havent stored the user name unless youve provided for this directly in your adapter. youll need to do something like:
$auth->getStorage()->UserName = 'myusername';
Then you can access with $authData = new Zend_Session_Namespace('Zend_Auth'); $username = $authData->UserName;.
Take a closer look at how the Zend_Auth_Adapter_Db works.
This is my approach and it s working nice:
1-i start by defining an init function in the bootstrap
protected function _initSession()
{
$UserSession = new Zend_Session_Namespace('UserSession');
$UserSession->setExpirationSeconds(/* you may fix a limit */);
Zend_Registry::set('UserSession', $UserSession);
}
/* in the Login action,after correct username & pwd */
// Create session
$UserSession = Zend_Registry::get('UserSession');
// Get the user from database or just from fields
//you have to make sure that the psswd is encrypted use MD5 for example..
$db = Zend_Db_Table::getDefaultAdapter();
$user = $db->fetchRow("SELECT * FROM user_table WHERE user_email = '".$user_email."'");
//then you assign to $user to $UserSession variable :
$UserSession->user = $user;
//finaly don't forget to unset session variable in the Logout action ...

Zend Framework User Authentication

What is the best practice for user website/REST authentication in ZV MVC? How and where to put the code in the ZF framework? Can you provide me a code example?
I have a website and a REST server written in Zend Framework but no user session jet implemented.
THX!
Authentication is setup in the _initAutoload of the bootstrap file, e.g. like this:
if(Zend_Auth::getInstance()->hasIdentity()) {
Zend_Registry::set('role', Zend_Auth::getInstance()
->getStorage()->read()->role);
}else{
Zend_Registry::set('role', 'guests');
}
In case of a REST authentication you might need to authenticate by just passing the login parameters instead of logging in through a form.
So it might look like this in your AuthenticationController:
private function getAuthAdapter() {
$authAdapter = new Zend_Auth_Adapter_DbTable(
Zend_Db_Table::getDefaultAdapter());
$authAdapter->setTableName('users') // the db table where users are stored
->setIdentityColumn('email')
->setCredentialColumn('password')
->setCredentialTreatment('SHA1(CONCAT(?,salt))');
return $authAdapter;
}
public function logoutAction() {
Zend_Auth::getInstance()->clearIdentity();
$this->_redirect('index/index');
}
public function loginAction(){
if (Zend_Auth::getInstance()->hasIdentity()){
$this->_redirect('index/index');
}
if ($request->isPost()){
$username = $request->getPost('username');
$password = $request->getPost('password');
if ($username != "" && $password != "") {
$authAdapter = $this->getAuthAdapter ();
$authAdapter->setIdentity($username)
->setCredential($password);
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($authAdapter);
if($result->isValid()){
$identity = $authAdapter->getResultRowObject();
$authStorage = $auth->getStorage();
$authStorage->write($identity);
$this->_redirect ( 'index/index' );
}
}
}
}
If you need more help on zend_auth and zend_acl you might have a look at this how to.