You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 13:07:53