【问题标题】:Override default Laravel EnsureEmailIsVerified middleware not firing覆盖默认 Laravel EnsureEmailIsVerified 中间件未触发
【发布时间】:2021-09-23 23:59:51
【问题描述】:

我正在使用 Laravel 8 构建一个 rest api。我想覆盖默认的 EnsureEmailisVerified 中间件并将我拥有的代码从控制器移动到该中间件中。

我的登录控制器中用于检查电子邮件是否已验证的代码是;

if (!$user->hasVerifiedEmail()) {
    return response()->json([
        'message' => 'You need to confirm your account. We have sent you an activation link to your email.'
    ], 422);
}

这很好用,但我想把它移出控制器,所以我创建了一个中间件并将代码移入其中,如下所示;

class EnsureEmailIsVerified
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next): mixed
    {
        if (! $request->user() ||
            ($request->user() instanceof MustVerifyEmail &&
                ! $request->user()->hasVerifiedEmail())) {
            return response()->json([
                'message' => 'You need to confirm your account. We have sent you an activation link to your email.'
            ], 422);
        }

        return $next($request);
    }
}

然后在我的Kernel.php 文件中添加;

'verified' => \App\Http\Middleware\EnsureEmailIsVerified::class,

然后我的登录路径是这样的;

Route::post('login', [Auth\AuthenticationController::class, 'login'])->middleware('verified');

问题是它根本没有触发......当我点击登录路由时,它似乎没有检查电子邮件是否经过验证,只是让用户登录。

【问题讨论】:

  • $request->user() 将在中间件上返回 null。在我的情况下,我在用户表上有一个status 字段,我检查if (auth()->user()->status == 0) { ... }。您可以在您的路由上使用 web 中间件,然后您可以在您的 verified 中间件上使用 auth()->user()->hasVerifiedEmail()

标签: php laravel laravel-middleware


【解决方案1】:

您已将中间件设置为在身份验证路由运行之前运行。然而,身份验证路由是用户登录的地方。在中间件运行时,身份验证尚未发生。您需要将中间件切换到在主控制器请求之后运行的中间件:

class EnsureEmailIsVerified
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next): mixed
    {
        $response = $next($request);
        // $request->user() may also work
        if (auth()->check() &&
            (auth()->user() instanceof MustVerifyEmail &&
                !auth()->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 $response;

    }
}

【讨论】:

  • 啊,假设我正在使用 Auth::attempt 是吗? ....由于我使用的是休息 API,我不使用该方法来返回令牌。我只是检查哈希密码
  • @CodeSauce 为了获得更好的体验,您应该考虑使用适用于您的身份验证过程的身份验证防护(或者如果您找不到有效的防护,则实施一个)。能够使用auth() 助手非常有用。无论如何,在您的情况下,您需要以某种方式知道控制器中的身份验证成功
  • 我在用圣所……你说的守卫是这个意思吗?
  • @CodeSauce 是的,Sanctum 包含自己的身份验证保护,您应该使用它来确保 auth() 帮助程序正常工作
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-30
  • 1970-01-01
  • 1970-01-01
  • 2019-09-04
  • 2019-10-16
  • 2011-12-20
相关资源
最近更新 更多