
本文详解 Laravel 8 中密码验证的核心机制:不直接比对明文,而是使用 Hash::check() 或内置 Auth::attempt() 安全校验用户输入密码与数据库中 bcrypt 哈希值是否匹配。
本文详解 laravel 8 中密码验证的核心机制:不直接比对明文,而是使用 `hash::check()` 或内置 `auth::attempt()` 安全校验用户输入密码与数据库中 bcrypt 哈希值是否匹配。
在 Laravel 8 中,绝不能像原始代码中那样通过 WHERE password = ? 直接查询数据库(即 $data = DB::table('users')->where(['username'=>$username, 'password'=>$password])->first();),因为数据库中存储的是经 bcrypt 加密的哈希值(如 $2y$10$...),而用户提交的是明文密码——二者类型与长度完全不同,直接等值匹配必然失败,且严重违背安全原则(暴露密码比较逻辑、绕过哈希校验、易受时序攻击)。
✅ 正确做法分两步:
- 按用户名(或其他唯一字段)查询用户记录;
-
使用
Hash::check()对比明文密码与数据库中的哈希值。
以下是推荐的两种实现方式:
方式一:手动校验(适合自定义逻辑场景)
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use App\Models\User; // 确保使用 Eloquent 模型而非 DB facade
class MainController extends Controller
{
public function login(Request $request)
{
$username = $request->input('username');
$password = $request->input('password');
// 1. 先根据 username 查找用户(注意:使用 User 模型,非 DB::table)
$user = User::where('username', $username)->first();
// 2. 验证用户存在且密码匹配
if (!$user || !Hash::check($password, $user->password)) {
$notification = [
'message' => '用户名或密码错误!',
'alert-type' => 'error'
];
return back()->with($notification);
}
// 3. 登录成功:存入 session(Laravel 推荐使用 auth() 会话管理)
$request->session()->put('user', $user);
return redirect('dashboard');
}
}⚠️ 注意事项:
- 必须引入
Illuminate\Support\Facades\Hash;- 使用
App\Models\User模型(确保$fillable或guarded设置合理,且密码字段未被批量赋值);Hash::check()自动识别 bcrypt 哈希格式并执行恒定时间比对,防御时序攻击。
方式二:使用 Laravel 内置认证(推荐,默认且最安全)
Laravel 提供开箱即用的 Auth::attempt() 方法,它自动完成查找 + 哈希校验 + Session 初始化全流程:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class MainController extends Controller
{
public function login(Request $request)
{
// 尝试登录:自动按 credentials 查找用户,并校验密码哈希
if (Auth::attempt(['username' => $request->username, 'password' => $request->password])) {
return redirect('dashboard');
}
// 认证失败
return back()->with([
'message' => '用户名或密码错误!',
'alert-type' => 'error'
]);
}
}✅ 优势:
- 自动处理密码哈希比对、Session 绑定、记住我(remember token)等;
- 支持多守卫(guard)、自定义用户提供器(provider);
- 与 Laravel 的
auth中间件无缝集成(如auth:web)。
补充说明
- 数据库密码字段必须为
VARCHAR(255)或更长,以兼容 bcrypt 输出(通常 60 字符); - 用户注册时务必使用
Hash::make($password)加密后再保存; - 若使用
Auth::attempt(),请确保User模型实现了Authenticatable合约(默认已实现); - 不建议手动管理
session()->put('user', ...),应优先使用Auth::login($user)或依赖Auth::attempt()的完整流程。
掌握这两种方式,你就能在 Laravel 8 中安全、规范地完成密码验证,兼顾可维护性与安全性。


















