在2.0之前的CakePHP中,您可以允许用户使用其电子邮件地址登录,方法是停止autoRedirect,然后将用户名数据与数据库中的电子邮件列进行比较(显然,如果不是电子邮件,Cake可以回退到用户名检查)。
在CakePHP 2.0中,这一点已经改变,您可以使用$this->Auth->login()
手动登录
我的问题是如何在2.0中实现这一点?我有一些非常复杂的代码,可以做各种事情,比如处理ajax和回发请求,如果用户尝试登录太多次,则锁定帐户等等,所以时间很长!
正如你所看到的,我手动检查帐户是否真的存在,这样我就可以在进行身份验证过程之前显示一条未找到帐户的消息,如果有5次尝试失败,我也可以使用它来锁定该用户的帐户。
这里的主要问题是允许系统检查用户名和电子邮件地址以进行身份验证,如果你在上述检查中使用电子邮件地址,系统会锁定用户,但它总是会失败,因为身份验证无法处理它。
希望有人能帮忙,提供一些想法和建议。感谢
if ($this->request->is('post'))
{
$opts = array(
'conditions'=>array(
'OR'=>array(
'User.username'=>$this->data['User']['username'],
'User.email'=>$this->data['User']['username']
)
)
);
$user = $this->User->find('first', $opts);
if(!empty($user))
{
if($user['User']['status'] == 0)
{
if($this->request->is('ajax'))
{
$this->autoRender = false;
echo json_encode(array('authenticated'=>false,'error'=>__('Sorry your account is currently locked. Please reset your password.?')));
}
else
{
$this->Session->setFlash(__('Sorry your account is currently locked. Please reset your password.'), 'default', array(), 'auth');
}
}
else
{
if ($this->Auth->login())
{
if ($this->request->is('ajax'))
{
$this->autoRender = false;
if(isset($this->params['url']['continue']))
{
$pathtoredirect = $this->UrlEncode->base64url_decode($this->params['url']['continue']);
echo json_encode(array('authenticated'=>true,'redirect'=>$pathtoredirect,'base'=>false));
}
else
{
$pathtoredirect = $this->Auth->redirect();
echo json_encode(array('authenticated'=>true,'redirect'=>$pathtoredirect,'base'=>true));
}
}
else
{
if(isset($this->params['url']['continue']))
{
$pathtoredirect = $this->UrlEncode->base64url_decode($this->params['url']['continue']);
}
else
{
$pathtoredirect = $this->Auth->redirect();
}
return $this->redirect($pathtoredirect);
}
}
else
{
if($this->Session->read('attempts'))
{
$attempts = $this->Session->read('attempts') + 1;
}
else
{
$attempts = 1;
}
$this->Session->write('attempts', $attempts);
if($attempts >= 5)
{
$this->User->id = $user['User']['id'];
$this->User->saveField('status', 0);
if ($this->request->is('ajax'))
{
$this->autoRender = false;
echo json_encode(array('authenticated'=>false,'error'=>__('Username or password is incorrect. For security reasons this account has now been locked and you must reset your password to unlock it.')));
}
else
{
$this->Session->setFlash(__('Username or password is incorrect. For security reasons this account has now been locked and you must reset your password to unlock it.'), 'default', array(), 'auth');
}
}
else
{
if ($this->request->is('ajax'))
{
$this->autoRender = false;
echo json_encode(array('authenticated'=>false,'error'=>__('Username or password is incorrect')));
}
else
{
$this->Session->setFlash(__('Username or password is incorrect'), 'default', array(), 'auth');
}
}
}
}
}
else
{
if ($this->request->is('ajax'))
{
$this->autoRender = false;
echo json_encode(array('authenticated'=>false,'error'=>__('Sorry that account does not exist.')));
}
else
{
$this->Session->setFlash(__('Sorry that account does not exist.'), 'default', array(), 'auth');
}
}
}
我不确定AuthComponent是否可以配置为自动检查两个字段,但这里有一个替代方案:
/*
* AppController
*/
beforeFilter()
{
$this->Auth->authenticate = array('Form' => array('fields' => array('username' => 'email', 'password' => 'password')));
}
/*
* UsersController
*/
function login()
{
if($this->request->is('post'))
{
$logged_in = false;
if($this->Auth->login())
{
$logged_in = true;
}
else
{
$this->Auth->authenticate = array('Form' => array('fields' => array('username' => 'username', 'password' => 'password')));
$this->Auth->constructAuthenticate();
$this->request->data['User']['username'] = $this->request->data['User']['email'];
if($this->Auth->login())
{
$logged_in = true;
}
}
if($logged_in)
{
/*
* Do what you want here
*/
}
else
{
/*
* Do what you want here
*/
}
}
}
当然,如果您想只执行一个测试来检查两个字段,可以将此代码移动到Component中,而不是直接调用$this->Auth->login()
方法。