Laravel Auth :: Attempt仅在第一次验证

时间:2014-07-22 03:32:44

标签: php laravel-4

我在Laravel身上遇到了一个奇怪的问题。

正常创建用户后,用户可以首次登录 ,但在此之后,Auth::attempt始终会失败。我只能通过代码更新用户密码再次登录,当我检查数据库时,所有密码都被正确哈希。

我似乎无法理解为什么会这样。这是我的代码

注册方法

$user = new User;
$user->username = Input::get('username');
$user->email = Input::get('email');
$user->password = Input::get('password');
$user->save();
$general = Role::find(3);
$user->roles()->attach($general->id);

登录方式

$username = Input::get('username');
$pwd = Input::get('password');
if (!($pwd && $username)) {
    return Redirect::intended('user/login')->withMessage('Emtpy username/password')->withInput();
}
if (Auth::attempt(array('username' => $username, 'password' => $pwd))){
    return Redirect::intended('user/dashboard');
}
elseif (Auth::attempt(array('email' => $username, 'password' => $pwd))) {
    return Redirect::intended('user/dashboard');
}
else {
    return Redirect::intended('user/login')->withMessage('Incorrect username/password')->withInput();
}

用户模型

public static function boot()
{
    parent::boot();

    static::saving(function($data) {
        $data->password = Hash::make($data->password);
        unset($data->password_confirmation);
        return true;
    });
}

4 个答案:

答案 0 :(得分:5)

问题是您使用的是wrong event listener

您错误地挂钩了save事件,每当对用户模型进行更改时都会调用(即creating和{{1} })。

这意味着每次用户登录,并执行某些操作(更新登录计数,更改其名字等) - 它会导致模型重新散列已经散列的密码,从而呈现它坏了。

有两种方法可以解决这个问题。

选项一是将事件更改为仅适用于updating事件。但这意味着稍后当您需要更新用户密码时,它将无法正确重新散列,因此选项2更好。

选项2是不使用任何事件,and just use a mutator function - 专为此完全情况而设计。

creating

这样,无论在何时/何时更改用户密码,都会进行哈希处理,但只有在实际需要更改时才会进行哈希处理。

答案 1 :(得分:1)

我能够通过覆盖默认的eloquent save方法来解决我的问题,并在创建用户时手动创建哈希。这是代码:

public function save(array $options = array())
{
    if (isset($this->password_confirmation))
    {
        unset($this->password_confirmation);
    }
    if (isset($this->password))
    {
        if (Hash::needsRehash($this->password))
        {
            $this->password = Hash::make($this->password);
        }
    }
    parent::save();
}

然而,我仍然无法一遍又一遍地发现为什么这种奇怪的经历正在发生。我仍然有重现错误的代码(即使在2014年7月22日完全安装了Laravel 4.2 ),并且可以将它提供给有兴趣调查此问题的任何人。

我使用的包是Zicaco Entrust和Laravel Frozennode。

答案 2 :(得分:0)

整个方法是复杂的方法。做起来很简单。

将您的注册方法更改为:

$user = new User;
$user->username = Input::get('username');
$user->email = Input::get('email');
$user->password = Hash::make(Input::get('password'));
$user->save();
$general = Role::find(3);
$user->roles()->attach($general->id);

扔掉你的" boot" -method。

另外(不太相关,但我喜欢这样做)你可以将登录程序改为:

$username = Input::get('username');
$pwd = Input::get('password');
if (!($pwd && $username)) {
    return Redirect::intended('user/login')->withMessage('Emtpy username/password')->withInput();
}
if (Auth::attempt(array('username' => $username, 'password' => $pwd)) 
    || Auth::attempt(array('email' => $username, 'password' => $pwd))){
        return Redirect::intended('user/dashboard');

    }
    else {
        return Redirect::intended('user/login')->withMessage('Incorrect username/password')->withInput();
    } 

答案 3 :(得分:-1)

在我看来你的问题就在这里:

if (Auth::attempt(array('username' => $username, 'password' => $pwd))){
***return Redirect::intended('user/dashboard');***
}
elseif (Auth::attempt(array('email' => $username, 'password' => $pwd))) {
    return Redirect::intended('user/dashboard');

如果您的第一次Auth尝试使用用户名失败,它将在第二次Auth尝试阻止之前返回方法的重定向。这可能不是您面临的整体问题,但它似乎仍然是一段错误的代码。