Raymien Posted July 29, 2013 Share Posted July 29, 2013 Hello boys and girls, I've been looking at a way to maintain access to the user name when using the Custom Authentication by email, as explained in the book. I think logging in via email is a good idea, as I still have members to our Curling site, who are quite forgetful of their usernames, but email's tend to not change. That being said, I've got at least one player who has actually gotten himself 3 different user accounts, because he forgets his username. On the flip side, many folks like to be called by their names, be it a pseudonym, or their actual name, rather than johnny274@gmail.com. So I tried what I thought would work, by setting the username much in the same way as the id as shown in the book. It didn't work. Then I noticed in the blog, a commenter asked a similar question (Josh) and found a solution that worked for him. Which was surprising similar to what I thought would work. So I tried that, and it still didn't work. So obviously I'm missing something. To note, I have been coding for many years now, longer than I care to admit, but I'm kinda new to the Yii framework, so please be gentle! Here's the code: UserIdentity private $_name; . . . //within the authenticate function $this->_name = $user->username; . . . public function getUsername(){ return $this->_name; } I'm sure you'll all laugh and say, "That's obvious!" and after I read it, I'll smack myself in the head for missing it, but anyway. :-) Thanks, Ray Link to comment Share on other sites More sharing options...
Larry Posted July 30, 2013 Share Posted July 30, 2013 There's nothing obviously wrong in this little snippet of code. It depends upon what $user is, whether $user->username has a value, and how the getUsername() method is being called. It looks like you're on the right track, however. Link to comment Share on other sites More sharing options...
Raymien Posted August 13, 2013 Author Share Posted August 13, 2013 Maybe I should step back a bit, and trace the login process, which starts with LoginForm: $this->_identity=new UserIdentity($this->username,$this->password); //becomes $this->_identity=new UserIdentity($this->email,$this->password); UserIdentity is the component which incorporates the new db authenticate function, and Larry clearly shows/reminds us that email is now username. // Understand that email === username $user = User::model()->findByAttributes(array('email'=>$this->username)); Now, if I understand correctly, $user is the local variable accessing the user model ($user = User::model()), and that if I want $user to include username, I'd need to modify the model. That's the part I'm confused about. (sorry if I seem to be rambling, I'm trying to sort through this again in my head.) Maybe it would be easier to just query the db to get the proper username that matches the email, and construct the User with that, then validate the password? Push me in the right direction please, I think I'm starting to get a headache. Ray Link to comment Share on other sites More sharing options...
Edward Posted August 13, 2013 Share Posted August 13, 2013 These parts of code can get complicated. Actually you don't need to alter the model because username is already available via $this->username in UserIdentity because $this->_identity=new UserIdentity($this->username,$this->password); as you can see in the above code snipet, the username and password were already passed to the UserIdentity class on its creation in public function login(). class UserIdentity extends CUserIdentity 'This is worth looking at in more detail' Okay now we are in CUserIdentity below you can see the public $username and $password class CUserIdentity extends CBaseUserIdentity { /** * @var string username */ public $username; /** * @var string password */ public $password; /** * Constructor. * @param string $username username * @param string $password password */ public function __construct($username,$password) { $this->username=$username; $this->password=$password; } So in your userIdentity class something basic like this will do the trick class UserIdentity extends CUserIdentity { private $_id; public function authenticate() { // Load model for username and email by active record $user = User::model()->findByAttributes(array('username'=>$this->username)); if($user === null) $this->errorCode=self::ERROR_USERNAME_INVALID; else if($user->password !== hash_hmac('sha256', $this->password, Yii::app()->params['encryptionKey'])) $this->errorCode=self::ERROR_PASSWORD_INVALID; else { $this->errorCode = self::ERROR_NONE; $this->_id = $user->id; } return !$this->errorCode; } public function getId() { return $this->_id; } } I hope this helps you get the picture, it took me a while to work that part out myself. Link to comment Share on other sites More sharing options...
Raymien Posted August 13, 2013 Author Share Posted August 13, 2013 Hi Edward, I think you may have missed part of this topic. I'm using email authentication, rather than username authentication, in which the username is replaced by email in the user creation. Ray Link to comment Share on other sites More sharing options...
Edward Posted August 13, 2013 Share Posted August 13, 2013 Do you need help to implement email authentication? Okay i just got a cup of Tea and a lump of chocolate, i am onto it now. Link to comment Share on other sites More sharing options...
Edward Posted August 13, 2013 Share Posted August 13, 2013 You could authenticate email with your statement if email was passed in place of username $user = User::model()->findByAttributes(array('email'=>$this->username)); That statement seems valid to me. If you wanted to find username you would only then need to do this $username = $user->username; (After you run your above statement) Because you have already received the user record from the email instead. Take into account if you do this you would need to change UserIdentity.php. I would also override the contructor of UserIdentity.php and change to take in parameters $email and $password as apposed to $username and $password. Link to comment Share on other sites More sharing options...
Recommended Posts