[英]CakePHP Login with both username and email using Auth Component
I want the auth component to allow user to login entrying either username or email. 我希望auth组件允许用户登录输入用户名或电子邮件。 In my users table, both fields - userName and userEmail are unique. 在我的用户表中,两个字段-userName和userEmail是唯一的。 At time of registration, the password is generated like: 注册时,生成的密码如下:
sha1($username.$password); SHA1($用户名密码$);
The problem is that user is not able to login using email. 问题是用户无法使用电子邮件登录。
App Controller 应用控制器
var $components = array('Auth');
public function beforeFilter(){
if(isset($this->params['prefix']) && $this->params['prefix'] == 'webadmin') {
$this->Auth->userModel = 'Admin';
$this->Auth->logoutRedirect = $this->Auth->loginAction = array('prefix' => 'webadmin', 'controller' => 'login', 'action' => 'index');
$this->Auth->loginError = 'Invalid Username/Password Combination!';
$this->Auth->authError = 'Please login to proceed further!';
$this->Auth->flashElement = "auth.front.message";
$this->Auth->loginRedirect = array('prefix'=>'webadmin', 'controller'=>'dashboard', 'action'=>'index');
}
else{
$this->layout="front";
//$this->Auth->autoRedirect = false;
// $this->Auth->logoutRedirect = $this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
// $this->Auth->loginRedirect = array('controller'=>'blogs', 'action'=>'index');
$this->Auth->fields = array(
'username' => 'userName',
'password' => 'password'
);
$this->Auth->userScope = array('User.status'=>1);
$this->Auth->loginError = "The username/email and password you entered doesn't match our records.";
$this->Auth->authError = 'Please login to view this page!';
$this->Auth->flashElement = "auth.front.message";
$this->Auth->loginRedirect = array('controller'=>'profiles', 'action'=>'index');
}
Users Controller : the login function goes like: 用户控制器 :登录功能类似于:
if(!empty($this->data))
{
// Try to login with Email
if (!empty($this->Auth->data)) {
// save username entered in the login form
$username = $this->Auth->data['User']['userName'];
// find a user by e-mail
$find_by_email = $this->User->find('first', array(
'conditions' => array('userEmail' => $this->Auth->data['User']['userName']),
'fields' => 'userName'));
// found
if (!empty($find_by_email))
{
$this->Auth->data['User']['userName'] = $find_by_email['User']['userName'];
$this->data['User']['password']=$this->Auth->data['User']['password'];
if (!$this->Auth->login($this->data)) {
// login failed
// bring back the username entered in the login form
$this->Auth->data['User']['username'] = $username;
} else {
$this->Session->delete('Message.auth');
// redirect
if ($this->Auth->autoRedirect) {
$this->redirect($this->Auth->redirect(), null, true);
}
}
}
}
}
Auth.php:(I have made some changes here in the way password is generated as I am using the cakephp session to auto-login to SMF forum.) Auth.php :(我在使用Cakephp会话自动登录SMF论坛时,在生成密码的方式上做了一些更改。)
function login($data = null) {
$data['User.password'] = sha1(strtolower($data['User.userName']) . $_POST['data']['User']['password']);
$this->__setDefaults();
$this->_loggedIn = false;
if (empty($data)) {
$data = $this->data;
}
if ($user = $this->identify($data)) {
$this->Session->write($this->sessionKey, $user);
$this->_loggedIn = true;
}
return $this->_loggedIn;
}
I took help from this link, but I am not getting username in $data['User.userName'] in auth.php, I getting email here, so the password goes wrong and results in login failure. 我把帮助从这个链接,但我不是auth.php获得在$数据的用户名[“User.userName”],我收到的电子邮件在这里,所以密码不顺心和登录失败的结果。
Please help. 请帮忙。
You have error in the conditions, it should be: 您的条件有误,应该是:
'conditions' => array('userEmail' => $this->Auth->data['User']['email']),
You are checking the username . 您正在检查用户名。
The only way I could make it work is by modifying auth.php in cake. 我唯一可以使它起作用的方法是在cake中修改auth.php。
App Controller I added this to the code in before filter: App Controller我将此添加到过滤器之前的代码中:
$this->Auth->fields = array(
'username' => 'userName',
'email'=>'userEmail',
'password' => 'password'
);
Users Controller I removed all the extra code. 用户控制器我删除了所有多余的代码。
Auth.php I made changes to the identify function to check email after encrypting the password in //the way I wanted. Auth.php我对identity函数进行了更改,以按照我希望的方式对密码进行加密后检查电子邮件。
function identify($user = null, $conditions = null) {
if ($conditions === false) {
$conditions = array();
} elseif (is_array($conditions)) {
$conditions = array_merge((array)$this->userScope, $conditions);
} else {
$conditions = $this->userScope;
}
$model =& $this->getModel();
if (empty($user)) {
$user = $this->user();
if (empty($user)) {
return null;
}
} elseif (is_object($user) && is_a($user, 'Model')) {
if (!$user->exists()) {
return null;
}
$user = $user->read();
$user = $user[$model->alias];
} elseif (is_array($user) && isset($user[$model->alias])) {
$user = $user[$model->alias];
}
if (is_array($user) && (isset($user[$this->fields['username']]) || isset($user[$model->alias . '.' . $this->fields['username']]))) {
if (isset($user[$this->fields['username']]) && !empty($user[$this->fields['username']]) && !empty($user[$this->fields['password']])) {
if (trim($user[$this->fields['username']]) == '=' || trim($user[$this->fields['password']]) == '=') {
return false;
}
$find = array(
$model->alias.'.'.$this->fields['username'] => $user[$this->fields['username']],
$model->alias.'.'.$this->fields['password'] => $user[$this->fields['password']]
);
} elseif (isset($user[$model->alias . '.' . $this->fields['username']]) && !empty($user[$model->alias . '.' . $this->fields['username']])) {
if (trim($user[$model->alias . '.' . $this->fields['username']]) == '=' || trim($user[$model->alias . '.' . $this->fields['password']]) == '=') {
return false;
}
// my code starts
$user['User.userEmail']=$user['User.userName'];
//find username using email
$find_by_email= $model->find('first', array(
'fields' => array('User.userName','User.realpass'),
'conditions' => array($model->alias.'.'.$this->fields['email'] => $user[$model->alias . '.' . $this->fields['email']]),
'recursive' => 0
));
if(!empty($find_by_email))
{
$uname=strtolower($find_by_email['User']['userName']);
$pwd=$user[$model->alias . '.' . $this->fields['password']];
}
else
{
$uname=strtolower($user[$model->alias . '.' . $this->fields['username']]);
$pwd=$user[$model->alias . '.' . $this->fields['password']];
}
$thepassword = sha1($uname.$pwd); // encrypt password
// find user where username or email equals to the username passed
$find = array(
'OR' => array($model->alias.'.'.$this->fields['username'] => $user[$model->alias . '.' . $this->fields['username']], $model->alias.'.'.$this->fields['email'] => $user[$model->alias . '.' . $this->fields['username']]),
$model->alias.'.'.$this->fields['password'] => $thepassword
);
} else {
return false;
}
$cond=array_merge($find, $conditions);
$data = $model->find('first', array(
'conditions' => $cond,
'recursive' => 0
));
// my code ends here
if (empty($data) || empty($data[$model->alias])) {
return null;
}
} elseif (!empty($user) && is_string($user)) {
$data = $model->find('first', array(
'conditions' => array_merge(array($model->escapeField() => $user), $conditions),
));
if (empty($data) || empty($data[$model->alias])) {
return null;
}
}
if (!empty($data)) {
if (!empty($data[$model->alias][$this->fields['password']])) {
unset($data[$model->alias][$this->fields['password']]);
}
return $data[$model->alias];
}
return null;
}
Lastly, I commented the password encrypt code to return the simple password so that I can encrypt it the wat I needed in the above function. 最后,我评论了密码加密代码以返回简单密码,以便可以对上述功能中所需的密码进行加密。
function password($password) {
//return Security::hash($password, null, true);
return $password;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.