如何在API路由中使用认证?解决Auth::user()返回null问题
嘿,这个问题我碰到过好多次了,Laravel里web和api路由的认证机制确实不一样,咱们一步步来解决:
Laravel的web路由组默认使用web中间件组,里面包含了StartSession、AuthenticateSession这些处理session认证的中间件,所以你在web路由里能直接拿到登录用户的信息。而api路由组默认用的是api中间件组,它默认是无状态的token认证,不会启动session,所以直接调用Auth::user()自然返回null。
下面是几种常用的解决办法,你可以根据自己的需求选:
1. 给api路由添加session支持(适合前后端同构或需要session的场景)
如果你想在api路由里也用session认证,只需要把web中间件里的会话相关中间件加到api路由里,或者直接给api路由组使用web中间件:
// routes/api.php Route::middleware(['web', 'auth'])->group(function () { Route::get('/user', function () { return Auth::user(); }); });
不过要注意,这样api就不再是无状态的了,更适合前后端在同一个域名下的场景。
2. 使用Laravel Sanctum(推荐给SPA或移动端API)
如果是做SPA或者移动端接口,Laravel Sanctum是官方推荐的轻量认证方案:
- 首先安装Sanctum:
composer require laravel/sanctum php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider" php artisan migrate
- 在
app/Http/Kernel.php的api中间件组里添加Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class - 给需要认证的api路由加上
auth:sanctum中间件:
// routes/api.php Route::middleware('auth:sanctum')->get('/user', function () { return Auth::user(); });
- 前端请求时,需要在请求头里带上
Authorization: Bearer {token};如果是同域SPA,Sanctum会自动处理cookie认证,不用手动带token。
3. 使用Laravel Passport(适合复杂的OAuth2场景)
如果你的API需要支持OAuth2的授权码、客户端凭证等复杂认证方式,可以用Passport:
- 安装Passport:
composer require laravel/passport php artisan migrate php artisan passport:install
- 在
config/auth.php里把api的认证驱动改成passport:
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'passport', 'provider' => 'users', 'hash' => false, ], ],
- 给api路由加上
auth:api中间件:
// routes/api.php Route::middleware('auth:api')->get('/user', function () { return Auth::user(); });
请求时同样需要在头里带上Bearer token。
4. 临时指定认证guard(不推荐正式环境用)
如果你只是临时测试,想在api里快速拿到session登录的用户,可以手动指定guard:
// routes/api.php Route::get('/user', function () { return Auth::guard('web')->user(); });
不过这种方法破坏了api的无状态特性,只适合临时调试。
不管用哪种方法,测试的时候可以用Postman或者curl发送请求,确保认证信息正确。比如用Sanctum的话,先通过登录接口拿到token,再请求/api/user时带上Authorization: Bearer your-token-here的请求头。
内容的提问来源于stack exchange,提问作者Ostap Brehin

