7.1 用户认证:员工卡与门禁系统


7.1 用户认证:员工卡与门禁系统

本节摘要:认证回答"你是谁"。Laravel 的 session 认证由四件零件组成:users 表的员工档案、session 会话、auth 中间件这道闸、bcrypt 密码哈希这枚防复制的卡芯。本节从零搭起注册、登录、登出与限流防爆破,拆解 Auth 门面背后每个零件在干什么,读完你能说清一次登录从提交密码到建立会话的完整过程。

登录窗背后不是一行代码

Auth::attempt($credentials) 一行就登录了,正因为它太方便,很多人从没弄清背后发生了什么。搞不清零件的代价是具体的:session 配置改错,登录态十秒就丢;不知道密码是哈希存的,调试时对着库里乱码发懵;没加限流,登录接口成为爆破入口。本节把每个零件拆开讲。

四件零件

  • users 表:员工档案。Laravel 默认迁移已备好,包含 name、email、password、remember_token 等字段,密码字段存的是哈希,不是原文。
  • session:登录后的通行记录。登录成功时框架把用户编号写进 session,后续请求凭这条记录认人,Cookie 里只存加密的 session 标识,不存敏感信息。
  • auth 中间件:门禁闸机。挂在路由组上,未登录者被重定向到登录页;API 场景下同名的 fallback 会返回 401。
  • Hash 门面:卡芯加工器。bcrypt 加盐哈希,同一密码每次哈希结果都不同,验证走专门的比对函数而不是字符串比较。

动手搭:注册、登录、登出

<?php // 注册:验证 + 哈希 + 落库 + 自动登录 use App\Models\User; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Hash; public function register(Request $request) { $data = $request->validate([ 'name' => ['required', 'string', 'max:50'], 'email' => ['required', 'email', 'unique:users,email'], 'password' => ['required', 'confirmed', 'min:8'], ]); $user = User::create([ 'name' => $data['name'], 'email' => $data['email'], 'password' => Hash::make($data['password']), // 只存哈希 ]); Auth::login($user); // 写 session 建立会话 return redirect()->route('orders.index'); }
<?php // 登录:attempt 一次完成"查人 + 验密 + 建会话" public function login(Request $request) { $credentials = $request->validate([ 'email' => ['required', 'email'], 'password' => ['required'], ]); // attempt 内部:按 email 查人、hash 校验、成功则写 session $remember = $request->boolean('remember'); if (Auth::attempt($credentials, $remember)) { $request->session()->regenerate(); // 换新会话标识,防会话固定攻击 return redirect()->intended(route('orders.index')); } // 统一话术:不区分"邮箱不存在"与"密码不对",不帮攻击者试错 return back()->withErrors(['email' => '邮箱或密码不正确']) ->onlyInput('email'); } // 登出:作废会话并换标识 public function logout(Request $request) { Auth::guard('web')->logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); return redirect()->route('login'); }

这段代码里藏着三个安全细节。regenerate() 在登录成功后换会话标识,掐断"会话固定"攻击(攻击者先把已知标识种给受害者);错误消息故意含糊,不给枚举邮箱的人反馈;regenerateToken() 换 CSRF 令牌,防止登出前的旧令牌被复用。安全不是额外的功能,是这些小动作的总和。

路由侧把门禁挂上(第三章的中间件在这里上岗):

<?php Route::middleware('guest')->group(function () { Route::get('/login', [AuthController::class, 'showLogin'])->name('login'); Route::post('/login', [AuthController::class, 'login']); }); Route::middleware('auth')->group(function () { Route::post('/logout', [AuthController::class, 'logout'])->name('logout'); // 所有需要登录的工位…… });

图 7-1:一次登录的完整认证流程

图 7-1:一次登录的完整认证流程

密码重置与防爆破

密码重置的标准流程是"发令牌邮件、凭令牌设新密码",Laravel 内置的 Password 门面把令牌生成、有效期、一次性使用都管理好了,业务侧只需配好邮件发送(下一章队列会接管发送的异步化)。防爆破靠两层:登录路由挂 throttle:5,1(每分钟最多五次),配合 attempt 的失败记录;更进一步可以引入验证码或双因素。认证的"多 guard"场景(比如员工端与客户端两套独立登录态)通过配置多个 guard 实现,每套 guard 指向各自的用户提供器与 session 仓,本节不展开,记住入口在 config 的 auth.php 即可。

💡 关键直觉:session 认证的所有状态都在服务端,Cookie 只是取件码。理解了这一点,"为什么改 session 配置会全站掉线""为什么 Cookie 清了就要重登"这类问题就都自明了。

本节要点回顾

  • 四件零件:档案表、session、auth 闸机、哈希加工,一次登录就是四件零件的接力。
  • 三个安全细节:登录后换会话标识、失败话术含糊、登出换 CSRF 令牌。
  • 防爆破:throttle 限流挂路由,密码重置交给 Password 门面托管令牌。
  • 边界:session 方案服务浏览器场景;API 场景的通行证是下一节 Sanctum 的主场。

门禁认了人,接下来回答"认完人给什么权限"。下一节把授权策略、Gate 与 API 通行证一次讲清。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U