You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 8重写默认EnsureEmailIsVerified中间件不触发如何解决

问题根因

你将verified中间件挂载到了登录路由上,而Laravel中间件的执行时机是控制器代码执行前,此时你还未在控制器中完成账号密码校验、用户身份识别的逻辑,$request->user()永远返回null,因此你写的中间件判断条件永远不会命中邮箱未验证的分支,自然不会触发校验。

解决方案

可根据你的业务需求二选一:

方案1:在登录环节拦截未验证邮箱的用户

如果你要在登录时就直接拦截邮箱未验证的用户,两种实现方式可选:

  • 推荐继续将校验逻辑保留在登录控制器中:登录环节本身就是身份校验的流程,在校验完账号密码有效性后再判断邮箱状态,是最符合逻辑的实现,不需要额外调整。
  • 如果一定要将逻辑抽离为中间件,需要调整中间件逻辑,先完成账号密码校验再判断邮箱状态:
public function handle(Request $request, Closure $next): mixed
{
    // 先校验账号密码有效性
    if (!Auth::attempt($request->only('email', 'password'))) {
        return response()->json(['message' => '账号或密码错误'], 401);
    }
    $user = Auth::user();
    // 校验邮箱状态
    if ($user instanceof MustVerifyEmail && !$user->hasVerifiedEmail()) {
        Auth::logout(); // 清除刚才生成的登录状态
        return response()->json([
            'message' => 'You need to confirm your account. We have sent you an activation link to your email.'
        ], 422);
    }
    return $next($request);
}

调整后登录路由挂载该中间件即可,控制器中无需重复做账号密码和邮箱状态校验。

方案2:登录后访问业务接口时校验邮箱状态

这是Laravel官方verified中间件的标准使用方式,符合REST API的常见设计规范:用户可以正常完成登录流程拿到身份凭证,但调用所有业务接口时会校验邮箱状态,未验证用户无法访问业务接口。
路由配置示例:

// 公开路由,无需登录即可访问
Route::post('login', [Auth\AuthenticationController::class, 'login']);

// 需登录且邮箱已验证才能访问的业务路由
Route::middleware(['auth:sanctum', 'verified'])->group(function () {
    // 所有需要权限的业务接口都放在该分组下
    Route::get('/user/profile', function (Request $request) {
        return $request->user();
    });
});

注意事项

  • 确认你的User模型已经实现了MustVerifyEmail接口,否则中间件中$request->user() instanceof MustVerifyEmail判断永远为false,会导致校验不触发。
  • 如果你使用的是JWT等非官方身份认证驱动,确认auth中间件已经正确配置,能够正常解析请求中的身份凭证获取用户对象。

内容的提问来源于stack exchange,提问作者BigJobbies

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 06:48:07