Yii-User Automatically Login The User After Click Activation

Dear all,

I am doing a project that allow user to automatically login after they click the activation link.

Here is my activation controller, i don’t see anything wrong but I just can’t login the user, each time the user clicks on the link it still not login the user…

Thanks!!!


<?php

......


if(isset($find->activkey) && ($find->activkey==$activkey)) {

				$find->activkey = UserModule::encrypting(microtime());

				$find->status = 1;

				$find->save();


$identity=new UserIdentity($find->username,$find->password);

if($identity->authenticate()){

    Yii::app()->user->login($identity);

}

else{

    echo $identity->errorMessage;

}

$lastVisit = User::model()->notsafe()->findByPk(Yii::app()->user->id);		$lastVisit->lastvisit = time();

$lastVisit->save();


			    $this->render('/user/message',array('title'=>UserModule::t("User activation"),'content'=>UserModule::t("<br>Welcome to my site. Your account is activated now.<br> You can <a href='http://mysite.com/user/profile'>Login Here</a>")));


			} else {

			    $this->render('/user/message',array('title'=>UserModule::t("User activation"),'content'=>UserModule::t("Incorrect activation URL.")));

			}

		} else {

			$this->render('/user/message',array('title'=>UserModule::t("User activation"),'content'=>UserModule::t("Incorrect activation URL.")));

		}

	}


}

Is you authenticate method returning true - are you hitting the login method??

Looks like you’re using the pwd field that’s returned from the DB. Is this pwd encrypted/hashed? If so, is your authenticate method taking that into account? I mean, is is rehashing again and failing?

Matt

Thanks for your help! All i want to do is automatically login the user. Right now even i get rid of the "authenticate", just login the user, it gives me the blank screen(all white) and not login the user (i am sure there is no syntax error…) i am using yii-user

Thanks again for your help!

This a basic code for the authorization of User.Which i genrally use and work like a charm. :)




 $identity = new UserIdentity($user->e_mail ,$user->password );

 $identity->authenticate();


// echo $identity->errorCode; 

                

                if($identity->errorCode === UserIdentity::ERROR_NONE) 

                {

                       Yii::app()->user->login($identity, NULL);

                      $this->redirect(array(('user/dasboard')));

                } else{

                      $this->redirect(array('site/index'));

                }

               



I hope it will help you.

Thanks,

Jayant

I use a special parameter jump for tell the identity to skip password validation:


            $identity=new UserIdentity($utente->email,null);

            $identity->jump= true;

            $identity->authenticate();

            Yii::app()->user->login($identity);

And the authenticate:




class UserIdentity extends CUserIdentity {

    private $_id;

    public $jump = false;

    public function authenticate() {




        $record=utente::model()->findByAttributes(array('email'=>$this->username));


        if($record===null)

            $this->errorCode=self::ERROR_USERNAME_INVALID;

        else if ($record->data_modifica == 0)

            $this->errorCode=self::ERROR_UNKNOWN_IDENTITY;

        else if (($this->jump== false) &&($record->password!==md5($this->password)))

            $this->errorCode=self::ERROR_PASSWORD_INVALID;

        else {

            $this->_id=$record->id;

            $this->setState('nome', $record->nome);

            $this->setState('cognome', $record->cognome);

            $this->setState('email', $record->email);


            $this->errorCode=self::ERROR_NONE;

        }

        return $this->errorCode;

    }


    public function getId() {

        return $this->_id;

    }

}




Yeah thats a good one zaccaria :)

Have you got regular authentication and login functionality working?

Can you post your *WebUser and *UserIdentity classes?

Matt

I already posted userIdentiy, web user is the standard one

It was directed @jiaming. He/She might have a custom implementation.

Thanks for your help…

I tried to jump the authenticate but still not work…


$identity=new UserIdentity($find->username,$find->password);


Yii::app()->user->login($identity);

Because it’s in activation controller so I really don’t need to test the user’s password or even username…

But this keeps giving me the blank screen.

It’s so weird…

Thanks for you guys help!!

You guys are so helpful and so nice.

I am using CWebUser and a normal userIdentity from yii-user module…

If you don’t need to authenticate the user, you can use changeIdentity.





$webUser = new CWebUser();

$webUser->changeIdentity($user->id, $user->username, array(

    'timezone' => $user->timezone,

 	...

));



But, if you’re getting a black screen, it could indicate somethings amiss with your routing/permissions. Are you even getting to the controller’s action?

Matt

Well, if I get rid of my code about UserIdentity, the activation controller behaves like a charm.

So the only problem would be the new code about userIdentity, which only contains 2 lines:


$identity=new UserIdentity($find->username,$find->password);


Yii::app()->user->login($identity);

Can I login the user with this code if I don’t need to check the username/password at all?


$webUser = new CWebUser();

$webUser->changeIdentity($user->id);

Thanks so much for your help!

Also, not sure what’s going on with your indentation but why do you have 2 else statements with the same output? I don’t know what’s preceding it so I’m guessing when I say this.





if (isset($find->activkey) && ($find->activkey == $activkey))

{

    $find->activkey = UserModule::encrypting(microtime());

    $find->status = 1;

    $find->save();


    $lastVisit = User::model()->notsafe()->findByPk(Yii::app()->user->id);

    $lastVisit->lastvisit = time();

    $lastVisit->save();


    $webUser = new CWebUser();

    $webUser->changeIdentity($lastVisit->id, $lastVisit->username, array());


    $this->render('/user/message', array('title' => UserModule::t("User activation"), 'content' => UserModule::t("<br>Welcome to my site. Your account is activated now.<br> You can <a href='http://mysite.com/user/profile'>Login Here</a>")));

}

else

{

    $this->render('/user/message', array('title' => UserModule::t("User activation"), 'content' => UserModule::t("Incorrect activation URL.")));

}



Yes, that will log the user in. By using changeIdentity, you’ll not fire the onBeforeLogin event and will skip over cookie authentication.

The login method uses changeIdentity to log the user in.





public function login($identity,$duration=0)

	{

		$id=$identity->getId();

		$states=$identity->getPersistentStates();

		if($this->beforeLogin($id,$states,false))

		{

			$this->changeIdentity($id,$identity->getName(),$states);


			if($duration>0)

			{

				if($this->allowAutoLogin)

					$this->saveToCookie($duration);

				else

					throw new CException(Yii::t('yii','{class}.allowAutoLogin must be set true in order to use cookie-based authentication.',

						array('{class}'=>get_class($this))));

			}


			$this->afterLogin(false);

		}

		return !$this->getIsGuest();

	}



I tried ur code but it gives me:

CWebUser and its behaviors do not have a method or closure named "changeIdentity".

It’s a protected method; you need to override the class. Mine looks like this.





<?php


/**

 * WebUser class file.

 *

 * @author Matt Skelton

 * @date 8-Jun-2011

 */


/**

 * Provides additional properties and functionality to CWebUser.

 */

class BNDWebUser extends CWebUser

{

    /**

     * Holds a reference to the currently logged in user model.

     * @var User The currently logged in User Model.

     */

    private $_model;


    /**

     * Retrieves a User model from the database

     * @param integer $id the id of the User to be retrieved

     * @return User the user model

     */

    public function loadUser()

    {

        if ($this->_model === null)

        {

            $this->_model = User::model()->findByPk($this->id);

        }


        return $this->_model;

    }


    /**

     * Changes the current logged in user's identity information

     * @param mixed $id the id that uniquely identifies the user

     * @param string $name the name used for display purposes

     * @param array $states a list of states that needs to be persisted across the session

     */

    public function changeIdentity($id, $name, $states = array())

    {

        parent::changeIdentity($id, $name, $states);

    }


    /**

     * Returns a boolean indicating if the user has completed registration

     * @return boolean if the user has completed registration

     */

    public function getIsRegistered()

    {

        $isRegistered = false;


        if (!$this->isGuest)

        {

            $user = $this->loadUser();


            if ($user)

            {

                $isRegistered = true;

            }

        }


        return $isRegistered;

    }


    /**

     * Returns a boolean indicating if the user logged in through an OpenId provider

     * @return boolean if the user logged in through an OpenId provider

     */

    public function getIsOpenIdUser()

    {

        $identifier = $this->getState('openIdIdentifier');


        return isset($identifier);

    }


    /**

     * Returns a boolean indicating if a user's account has been linked to the OpenId provider that they signed in with.

     * @return boolean if the accounts are linked

     */

    public function getIsOpenIdLinked()

    {

        $isLinked = false;


        if ($this->getIsOpenIdUser())

        {

            $openProfile = OpenProfile::model()->findByPk($this->getState('openIdIdentifier'));


            if ($openProfile->user_id === $this->id)

            {

                $isLinked = true;

            }

        }


        return $isLinked;

    }


    /**

     * Returns a boolean if the user is in Working Mode. In Working Mode, the user has

     * seleted an organization to work in.

     * @return boolean if the user is working

     */

    public function getIsWorking()

    {

        $isWorking = false;


        if ($this->getState('organizationName') && $this->getState('organizationId'))

        {

            $isWorking = true;

        }


        return $isWorking;

    }


    /**

     * Returns a boolean indicating is the user is working on the specified organization

     * @param type $organizationId the ID of the organization to query

     * @return boolean if the user is working on the organization

     */

    public function isWorkingOn($organizationId)

    {

        $isWorking = false;


        if ($this->getIsWorking() && ($this->getState('organizationId') === $organizationId))

        {

            $isWorking = true;

        }


        return $isWorking;

    }


    public function getRole()

    {

        return $this->getState('role');

    }


    public function getRoleForOrganization($organizationId)

    {

        $employee = Employee::model()->findByPk(array(

            'organization_id' => $organizationId,

            'user_id' => $this->id));


        return $employee->role->name;

    }


    public function isOwner($organizationId = null)

    {

        $roleName = $this->getRole();


        if ($organizationId)

        {

            $roleName = $this->getRoleForOrganization($organizationId);

        }


        return (strtolower($roleName) === Employee::ROLE_ADMIN);

    }


    public function isUser($organizationId = null)

    {

        $roleName = $this->getRole();


        if ($organizationId)

        {

            $roleName = $this->getRoleForOrganization($organizationId);

        }


        return (strtolower($roleName) === Employee::ROLE_USER);

    }


    public function canView($organizationId = null)

    {

        $canView = false;


        if ($this->isUser($organizationId) || $this->isOwner($organizationId))

        {

            $canView = true;

        }


        return $canView;

    }


    public function canModify($organizationId = null)

    {

        $canView = false;


        if ($this->isOwner($organizationId))

        {

            $canView = true;

        }


        return $canView;

    }


    /**

     * Returns a boolean indicating if the current user is an admin (proprietor) in at least 1 organization

     */

    public function getIsAProprietor()

    {

        $isProprietor = false;


        $user = $this->loadUser();


        foreach ($user->roles as $role)

        {

            if (strtolower($role->role->name) == Employee::ROLE_ADMIN)

            {

                $isProprietor = true;


                break;

            }

        }


        return $isProprietor;

    }

}

?>

[quote=“waterloomatt, post:17, topic:54558”]

It’s a protected method; you need to override the class. Mine looks like this.






[quote]



After adding the class changeIdentity

My web user look like this:


[code]<?php


class WebUser extends CWebUser

{


    public function getRole()

    {

        return $this->getState('__role');

    }

    

    public function getId()

    {

        return $this->getState('__id') ? $this->getState('__id') : 0;

    }


//    protected function beforeLogin($id, $states, $fromCookie)

//    {

//        parent::beforeLogin($id, $states, $fromCookie);

//

//        $model = new UserLoginStats();

//        $model->attributes = array(

//            'user_id' => $id,

//            'ip' => ip2long(Yii::app()->request->getUserHostAddress())

//        );

//        $model->save();

//

//        return true;

//    }




    public function changeIdentity($id, $name, $states = array())

    {

        parent::changeIdentity($id, $name, $states);

    }





    protected function afterLogin($fromCookie)

        {

        parent::afterLogin($fromCookie);

        $this->updateSession();

        }


    public function updateSession() {

        $user = Yii::app()->getModule('user')->user($this->id);

        $userAttributes = CMap::mergeArray(array(

                                                'email'=>$user->email,

                                                'username'=>$user->username,

                                                'create_at'=>$user->create_at,

                                                'lastvisit_at'=>$user->lastvisit_at,

                                           ),$user->profile->getAttributes());

        foreach ($userAttributes as $attrName=>$attrValue) {

            $this->setState($attrName,$attrValue);

        }

    }


    public function model($id=0) {

        return Yii::app()->getModule('user')->user($id);

    }


    public function user($id=0) {

        return $this->model($id);

    }


    public function getUserByName($username) {

        return Yii::app()->getModule('user')->getUserByName($username);

    }


    public function getAdmins() {

        return Yii::app()->getModule('user')->getAdmins();

    }


    public function isAdmin() {

        return Yii::app()->getModule('user')->isAdmin();

    }


}

But this still…

Not login the user at all…

What are you log files saying?

Also, post your entire controller action here.

My log files say nothin… This code is not causing me blank anymore, it redirect to the page i want but simply not login the user.





<?php


class ActivationController extends Controller

{

	public $defaultAction = 'activation';


	

	/**

	 * Activation user account

	 */

	public function actionActivation () {

		$email = $_GET['email'];

		$activkey = $_GET['activkey'];

		if ($email&&$activkey) {

			$find = User::model()->notsafe()->findByAttributes(array('email'=>$email));

			if (isset($find)&&$find->status) {


$webUser = new WebUser();

$webUser->changeIdentity($find->id, $find->username, array());


$this->render('/user/message',array('title'=>UserModule::t("User activation"),'content'=>UserModule::t("<br>Welcome to my site. Your account is activated now.<br> You can <a href='http://www.mysite.com/user/profile'>Login Here</a>")));




			} elseif(isset($find->activkey) && ($find->activkey==$activkey)) {

				$find->activkey = UserModule::encrypting(microtime());

				$find->status = 1;

				$find->save();


$webUser = new WebUser();

$webUser->changeIdentity($find->id, $find->username, array());


$this->render('/user/message',array('title'=>UserModule::t("User activation"),'content'=>UserModule::t("<br>Welcome to mysitt. Your account is activated now.<br> You can <a href='http://www.mysite.com/user/profile'>Login Here</a>")));


			} else {

			    $this->render('/user/message',array('title'=>UserModule::t("User activation"),'content'=>UserModule::t("Incorrect activation URL.")));

			}

		} else {

			$this->render('/user/message',array('title'=>UserModule::t("User activation"),'content'=>UserModule::t("Incorrect activation URL.")));

		}

	}


}




This will not login the user…

Thanks so much for your help!