Laravel多Guard配置问题:API用JWT、Web用Session鉴权失效
解决Laravel多Guard认证问题:Web路由使用Session Guard,API使用JWT Guard
嘿,我来帮你搞定这个问题!你现在遇到的核心问题是默认Guard被设为了api,所以所有默认的Auth操作(包括Auth::routes()生成的Web认证路由)都会优先使用JWT Guard,导致Web端的Session认证失效。下面给你几个实用的解决方法:
方法一:动态切换默认Guard(推荐)
这种方式最省心,不用改路由,系统会自动根据请求类型切换Guard。你只需要在AppServiceProvider的boot方法里加入逻辑,判断当前是API请求还是Web请求,然后动态设置默认Guard:
// app/Providers/AppServiceProvider.php public function boot() { // 根据请求路径判断,API请求用api guard,Web请求用web guard if (request()->is('api/*')) { config(['auth.defaults.guard' => 'api']); } else { config(['auth.defaults.guard' => 'web']); } }
这样一来,用户访问Web路由时自动用Session Guard,访问API路由时用JWT Guard,完全不用手动给每个路由指定。
方法二:给Web路由明确指定Guard
如果你不想动态修改默认Guard,也可以直接给Web路由绑定对应的Guard中间件:
方式1:用路由组包裹Web认证路由
把需要Web认证的路由放在auth:web中间件组里,强制使用Web Guard:
// routes/web.php // 公开路由(比如登录页)不需要中间件 Route::get('login', 'Auth\LoginController@showLoginForm')->name('login'); Route::post('login', 'Auth\LoginController@login'); Auth::routes(['register' => false]); // 如果需要保留默认Auth路由,可以这样,然后给需要认证的路由加中间件 // 需要认证的Web路由,指定web guard Route::middleware('auth:web')->group(function () { Route::get('/', 'HomeController@index')->name('home'); Route::get('/home', 'HomeController@index')->name('home'); });
方式2:手动定义Auth路由并指定Guard
如果你想完全控制认证路由,可以替换掉Auth::routes(),手动定义每个认证路由并绑定对应的Guard中间件:
// routes/web.php // 登录路由,未登录用户访问(guest:web中间件指定用web guard判断是否登录) Route::get('login', 'Auth\LoginController@showLoginForm')->name('login'); Route::post('login', 'Auth\LoginController@login')->middleware('guest:web'); // 登出路由,已登录用户访问(auth:web中间件指定用web guard验证) Route::post('logout', 'Auth\LoginController@logout')->name('logout')->middleware('auth:web'); // 注册路由(如果需要) Route::get('register', 'Auth\RegisterController@showRegistrationForm')->name('register'); Route::post('register', 'Auth\RegisterController@register')->middleware('guest:web'); // 密码重置路由同理,都加上对应的web guard中间件 Route::get('password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.request'); Route::post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.email'); Route::get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset'); Route::post('password/reset', 'Auth\ResetPasswordController@reset')->name('password.update');
额外注意点:自定义LoginController的Guard
如果你的Web端LoginController有自定义的guard()方法,一定要确保它返回Web Guard:
// app/Http/Controllers/Auth/LoginController.php protected function guard() { return Auth::guard('web'); }
如果没有这个方法,Laravel会使用默认Guard,而你默认设的是api,所以Web登录会走JWT验证,自然失效。加上这个方法就能强制Web登录用Session Guard。
内容的提问来源于stack exchange,提问作者Bob
相关产品推荐
相关产品推荐

