Laravel Auth退出功能失效:登出后未清缓存仍可访问受保护仪表盘
问题根因
- 核心原因:登出未指定对应Guard:你登录时使用的是自定义的
userGuard(Auth::guard('user')->attempt()),但登出时调用的Auth::logout()默认操作的是配置文件中设置的默认webGuard,自定义userGuard的登录会话完全没有被清除。你打印的会话数据中存在的login_user_59ba36addc2b2f9401580f014c7f58ea4e30989d字段就是userGuard的登录状态标识,未被清除自然可以正常访问受保护页面。 - 次要原因:浏览器页面缓存:即使登录状态被清除,浏览器如果缓存了仪表盘页面的内容,直接访问时会优先读取本地缓存,不走服务端的Auth中间件校验,也会出现可以访问的假象,这就是你清除缓存后权限控制恢复正常的原因。
修复方案
1. 修改登出逻辑,指定对应Guard操作
修改AuthenticationController.php中的logout方法,指定user Guard执行登出:
// 方法参数引入Request类 public function logout(Request $request) { // 对登录用的user guard执行登出 Auth::guard('user')->logout(); // 清空所有会话数据 Session::flush(); // 再生CSRF令牌,防范会话固定攻击 $request->session()->regenerateToken(); return redirect()->route('login')->with('success','You have logged out!'); }
2. 添加禁用缓存中间件,避免浏览器缓存受保护页面
第一步:创建中间件
执行Artisan命令创建禁止缓存中间件:
php artisan make:middleware DisableCache
第二步:编写中间件逻辑
编辑app/Http/Middleware/DisableCache.php文件:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; class DisableCache { public function handle(Request $request, Closure $next) { $response = $next($request); return $response->header('Cache-Control', 'no-cache, no-store, max-age=0, must-revalidate') ->header('Pragma', 'no-cache') ->header('Expires', 'Fri, 01 Jan 1990 00:00:00 GMT'); } }
第三步:注册并使用中间件
编辑app/Http/Kernel.php文件,在$routeMiddleware数组中添加注册项:
protected $routeMiddleware = [ // 原有其他中间件保持不变 'cache.disable' => \App\Http\Middleware\DisableCache::class, ];
修改web.php中的路由组,添加该中间件:
Route::group(['middleware' => ['auth:user', 'cache.disable']], function(){ Route::get('/dashboard','AuthenticationController@dashboard')->name('dashboard'); });
可选优化:修改登出请求为POST
GET请求容易被爬虫、浏览器预加载意外触发,建议将登出请求改为POST:
修改dashboard.blade.php中的登出表单:
<form action="{{url('logout')}}" method="POST"> @csrf <input type="submit" name="Submit" value="Logout"> </form>
同时修改web.php中的登出路由定义:
Route::post('/logout','AuthenticationController@logout')->name('logout');
内容的提问来源于stack exchange,提问作者peter anderson
相关产品推荐
相关产品推荐

