Laravel 弹性邮件验证:允许访客访问,强制登录用户验证

花韻仙語
发布: 2025-11-16 11:23:20
原创
783人浏览过

Laravel 弹性邮件验证:允许访客访问,强制登录用户验证

本文详细介绍了如何在 laravel 中实现灵活的邮件验证机制。通过创建自定义中间件,可以确保访客用户能够自由访问公共页面,而已登录用户则必须完成邮箱验证才能继续操作。这种方法解决了默认 `verified` 中间件对访客的限制问题,实现了用户体验与安全性的平衡。

在 Laravel 应用开发中,我们常常需要对用户进行邮箱验证以确保账户安全和信息准确性。Laravel 框架为此提供了开箱即用的邮件验证功能,包括 verified 中间件。然而,在某些场景下,我们可能希望允许未登录的访客访问网站的公共页面(例如博客文章、产品展示页),但一旦用户登录,无论访问任何页面,都必须先完成邮箱验证。

Laravel 默认的 verified 中间件在检测到用户未验证时,会尝试将用户重定向到登录页面(如果用户未认证),或者重定向到邮箱验证通知页面(如果用户已认证但未验证)。当我们将 middleware('verified') 应用于所有路由时,会导致一个问题:访客用户在访问公共页面时也会被强制要求登录,这与我们的需求相悖。

为了解决这一问题,我们可以创建一个自定义中间件,它能够区分访客用户和已登录用户,并仅对已登录但未验证的用户强制执行邮箱验证。

创建自定义中间件

首先,我们需要通过 Artisan 命令创建一个新的中间件。我们可以将其命名为 EnsureEmailIsVerifiedUnlessGuest,以明确其功能。

php artisan make:middleware EnsureEmailIsVerifiedUnlessGuest
登录后复制

该命令会在 app/Http/Middleware 目录下生成 EnsureEmailIsVerifiedUnlessGuest.php 文件。接下来,我们需要修改其 handle 方法,实现所需的逻辑:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\URL;
use Symfony\Component\HttpFoundation\Response;

class EnsureEmailIsVerifiedUnlessGuest
{
    /**
     * 处理传入的请求。
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next, string $redirectToRoute = null): Response
    {
        // 检查请求中是否存在已认证的用户,并且该用户需要邮箱验证但尚未验证
        if ($request->user() &&
            ($request->user() instanceof MustVerifyEmail &&
            ! $request->user()->hasVerifiedEmail())) {

            // 如果是 AJAX 请求,返回 403 错误
            if ($request->expectsJson()) {
                abort(403, '您的邮箱地址尚未验证。');
            }

            // 否则,重定向到邮箱验证通知页面
            return Redirect::guest(URL::route($redirectToRoute ?: 'verification.notice'));
        }

        // 如果用户是访客,或者用户已验证,则允许请求继续
        return $next($request);
    }
}
登录后复制

代码解析:

  • $request->user(): 检查当前请求是否存在已认证的用户。如果用户未登录,此方法将返回 null。
  • $request->user() instanceof MustVerifyEmail: 确保当前用户模型实现了 MustVerifyEmail 接口。Laravel 的默认 User 模型通常会实现此接口。
  • ! $request->user()->hasVerifiedEmail(): 检查已认证用户的邮箱是否尚未验证。
  • $request->expectsJson(): 判断请求是否期望 JSON 响应(例如,来自 API 或 JavaScript 的异步请求)。如果是,则返回 403 状态码和错误信息。
  • Redirect::guest(URL::route($redirectToRoute ?: 'verification.notice')): 如果用户已登录但未验证,则将其重定向到邮箱验证通知页面。$redirectToRoute 参数允许我们自定义重定向的目标路由,默认为 verification.notice。

注册中间件

创建完中间件类后,我们需要在 app/Http/Kernel.php 文件中将其注册到 $routeMiddleware 数组中,以便在路由中使用。

// app/Http/Kernel.php

protected array $routeMiddleware = [
    // ... 其他中间件
    'verified-or-guest' => \App\Http\Middleware\EnsureEmailIsVerifiedUnlessGuest::class,
];
登录后复制

这里我们将自定义中间件命名为 verified-or-guest。

应用中间件

现在,我们可以在路由定义中使用这个新的中间件了。将其应用到需要邮箱验证保护的路由组或单个路由上。

例如,如果你希望所有已登录用户在访问任何页面前都必须验证邮箱,你可以将此中间件应用到全局的 web 中间件组,或者应用到你的所有认证路由组:

// routes/web.php

use Illuminate\Support\Facades\Route;

Route::middleware(['web', 'verified-or-guest'])->group(function () {
    // 任何用户(包括访客)都可以访问的公共页面
    Route::get('/', function () {
        return view('welcome');
    });

    Route::get('/posts/{id}', function ($id) {
        return "Viewing Post {$id}";
    });

    // 只有已登录且已验证的用户才能访问的页面
    Route::get('/dashboard', function () {
        return "Welcome to your Dashboard!";
    })->middleware('auth'); // 注意:'auth' 中间件通常会放在 'verified-or-guest' 之后或同级
});

// 如果你只想保护特定的认证用户路由,可以这样使用:
Route::middleware(['auth', 'verified-or-guest'])->group(function () {
    Route::get('/profile', function () {
        return "User Profile";
    });
    // ... 其他需要认证和验证的路由
});
登录后复制

工作原理:

当请求进入 verified-or-guest 中间件时:

  1. 如果用户是访客 ($request->user() 为 null),条件判断不成立,中间件直接调用 $next($request),允许访客访问。
  2. 如果用户已登录 ($request->user() 存在):
    • 检查用户是否实现了 MustVerifyEmail 接口。
    • 检查用户是否已验证邮箱 (! $request->user()->hasVerifiedEmail())。
    • 如果用户已登录但未验证,则将其重定向到邮箱验证通知页面。
    • 如果用户已登录且已验证,则条件判断不成立,中间件直接调用 $next($request),允许用户访问。

注意事项与总结

  • 中间件顺序: 确保 verified-or-guest 中间件在 auth 中间件之后或与 auth 中间件同级。auth 中间件负责验证用户是否已登录,而我们的自定义中间件则是在用户已登录的基础上进行邮箱验证状态的检查。
  • 用户体验: 这种方法提供了一个更友好的用户体验,访客可以自由浏览公共内容,而登录用户则被引导完成必要的验证步骤,从而提升了应用的安全性。
  • 可扩展性: 你可以根据需要进一步定制中间件的逻辑,例如,为不同的路由指定不同的重定向目标,或者在验证失败时返回自定义的视图。

通过上述步骤,我们成功地在 Laravel 中实现了一个灵活的邮箱验证机制,既满足了对已登录用户强制验证的需求,又保证了访客用户对公共页面的无障碍访问。这种自定义中间件的方式是 Laravel 强大且灵活的中间件系统的一个典型应用。

以上就是Laravel 弹性邮件验证:允许访客访问,强制登录用户验证的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号