如何使用自定义登录表单比较Laravel的哈希密码?

9

你能帮我吗?我正在使用Laravel构建自己的登录表单。但是我有一个问题,因为我使用Hash方法存储了我的密码,在我的登录表单中再次使用hash方法进行比较。但我发现哈希值总是在变化。

以下是我的路由代码:

Route::post('/admin_handle_login', function()
{

    $rules = array(
        'admin_username'    =>  'required',
        'admin_password'    =>  'required'
    );

    $validate_admin_login = Validator::make(Input::all(), $rules);

    if($validate_admin_login->fails()) {

        $messages = $validate_admin_login->messages();

        Session::flash('warning_notification','Error: Incomplete details!');

        return Redirect::to('/flaxadmin')
                            ->withErrors($messages)
                            ->withInput(Input::except('admin_password'));

    } else {

        $d = array(
            Input::get('admin_username'), Hash::make(Input::get('admin_password'))
        );

        $validate_admin = DB::table('administrators')
                            ->select('username')
                            ->where('username', Input::get('admin_username'))
                            ->where('password', Hash::check('password', Input::get('admin_password')))
                            ->count();
        fp($d);
        fp($validate_admin);

    }

});

结果是

Array
(
    [0] => admin002
    [1] => $2y$10$RTwKHN9W1/unu1ZhYlNjauApJjjoNTBnE6td/AZ5jWgZEdqVav0um
)
0

在我的数据库中,admin002的密码为:
$2y$10$47sSXLzh/YXN6Rf2fmljYO7lZaxfhXVSUTp5bssR2gYQ6Nw9luUH2

我的代码有错吗?或者有没有更好的方法来做这个呢?我是 Laravel 的初学者。


你需要做的是在数据库中找到所有使用这个用户名的用户。然后你需要检查每个账户的密码。 - Jerodev
我知道这一点。但是我使用了哈希函数,每当页面重新加载或刷新时它就会改变。因此,如果我使用123作为密码,在我的数据库中也是123,但它们的哈希值不同。这就是为什么我无法得到精确的值。 - Jerielle
4个回答

21

首先,你不能以这种方式进行操作。 假设用户名是唯一的,你应该这样做:

$validate_admin = DB::table('administrators')
                            ->select('username')
                            ->where('username', Input::get('admin_username'))
                            ->first();

if ($validate_admin && Hash::check(Input::get('admin_password'), $validate_admin->password)) {
  // here you know data is valid
}

然而,你应该考虑使用内置方法而不是自己编写代码。如果你只想登录/检查带有密码的用户,则可以使用Auth::attemptAuth::validate,因此没有必要自己编写代码。


如果不存在用户会发生什么? - Daniel Gelling
@DanielGelling 我在if语句的开头添加了$validate_admin && - Marcin Nabiałek
好的,我已经使用了USER模型,但是我不知道如何更改或覆盖模型内部的表格。我知道的是Auth::validate正在使用User模型类。我在我的客户帐户中使用了这个,它可以工作,所以我决定为我的管理员帐户创建另一个登录。 - Jerielle
@Jerielle 所以你可能也可以看一下 https://dev59.com/zWMk5IYBdhLWcg3w_yvn - Marcin Nabiałek

4

在这里,您正在使用输入密码的散列版本检查字符串“password”。

因此,请尝试通过用户名获取用户,如果有结果,则可以将数据库中存储的密码的散列版本与输入密码进行比较。就像这样:

$user = DB::table('administrators')
        ->select('username', 'password')
        ->where('username', Input::get('admin_username');

if($user->count()) {
    $user = $user->first();
    if(Hash::check(Input::get('admin_password'), $user->password)) {
         //User has provided valid credentials :)
    }
}

我不知道这个答案是怎么得到赞的,IF条件是错误的,应该是Hash::check(Input::get('admin_password'),$user->password)。 - ayyanar pms
@ayyanarpms 您是正确的,确实(曾经)缺少了一个括号... - Daniel Gelling

2

对于marcin-nabiałek答案进行了微小的改进,现在您可以使用PHP的password_verify来实现相同的功能。

$user = App\User::where('email', $request->email)->first();

if($user && password_verify($request->password, $user->password)) {
   // authenticated user,
   // do something...
}

-1

这是有用的代码,100%适用于laravel 6/7/8。

if ($data = AddEmployee::where('name', $request->name)-first()) {
  $pass = Hash::check($request->password, $data->password);
  if ($pass) {
    echo "sucess";
  } else {
    echo "Password Not Valid";
  }
} else {
  echo "Username Not Valid" . "<br>";
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接