Laravel中如何实现可选邮箱验证,登录用户需验证后访问全站
Laravel实现登录用户强制邮箱验证、游客可访问公开路由的方案
核心思路
原生
verified中间件的逻辑是「必须登录+必须邮箱验证」,不符合游客可访问公开页的需求,我们需要自定义中间件实现:仅对已登录的用户校验邮箱验证状态,未登录游客直接放行
实现步骤
1. 创建自定义中间件
执行artisan命令生成中间件文件:php artisan make:middleware EnsureEmailVerifiedIfAuthed
打开生成的app/Http/Middleware/EnsureEmailVerifiedIfAuthed.php,替换handle方法逻辑:
public function handle(Request $request, Closure $next, $redirectToRoute = null) { // 仅当用户已登录时,才校验邮箱验证状态 if ($request->user() && ! $request->user()->hasVerifiedEmail()) { return $request->expectsJson() ? abort(403, 'Your email address is not verified.') : redirect()->route('verification.notice'); } return $next($request); }
2. 注册中间件
打开app/Http/Kernel.php,在$middlewareAliases数组中添加别名:
protected $middlewareAliases = [ // 其他原有中间件 'verified.if_authed' => \App\Http\Middleware\EnsureEmailVerifiedIfAuthed::class, ];
3. 挂载中间件到全局web组
为了让所有web路由都生效,不需要逐个路由添加,直接将中间件加入web中间件组,同样在app/Http/Kernel.php中修改:
protected $middlewareGroups = [ 'web' => [ // 其他原有web中间件,比如加密Cookie、Session启动之类的 \App\Http\Middleware\EnsureEmailVerifiedIfAuthed::class, ], ];
4. 配置例外路由
注意要排除邮箱验证相关、退出登录等路由,避免未验证用户无法完成验证操作:
可以直接在自定义中间件的开头添加例外判断,示例:
// 放在handle方法最开头,跳过指定路由 if ($request->is('email/*', 'logout')) { return $next($request); }
或者在路由定义时用withoutMiddleware跳过:
Route::get('/email/verify', [VerificationController::class, 'show']) ->name('verification.notice') ->withoutMiddleware('verified.if_authed');
效果验证
- 未登录游客访问
/、/posts/1等公开路由,可正常访问,无任何拦截 - 已登录但未验证邮箱的用户,访问任何站点页面都会跳转到邮箱验证提示页,完成验证后可正常访问
- 已登录且已验证邮箱的用户,无任何访问限制
内容的提问来源于stack exchange,提问作者user3569641
相关产品推荐
相关产品推荐

