Laravel API路由中如何正确提交存储并使用Session
问题原因
Laravel 默认对 web.php 和 api.php 加载的中间件组做了区分:api.php 下的路由默认走 api 中间件组,这个组默认是无状态设计,没有加载 Session 启动、Cookie 加密/传输相关的中间件。你调用 session()->put() 写入的数据只会在单次请求生命周期里存在,请求结束后不会持久化,下次访问 /test2 时会生成全新的会话,自然拿不到之前存的值,返回 null。
解决方法
两种方案可选,优先推荐第二种按需加载的方式,避免给不需要 Session 的接口增加额外开销。
方案1:全局给API路由开启Session支持
打开 app/Http/Kernel.php 文件,找到 $middlewareGroups 属性下的 api 配置项,把 Session 依赖的几个中间件加进去:
'api' => [ 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, // 新增以下3个和Cookie、Session相关的中间件 \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, ],
修改后所有 api.php 下的路由都可以正常操作 Session。
方案2:仅给需要Session的路由单独加载中间件(推荐)
不需要修改全局 api 中间件组,直接在路由定义时,给需要用 Session 的路由单独包裹对应的中间件即可,不影响其他无状态接口:
Route::prefix('v1')->namespace('Api\v1')->group(function(){ // 仅给需要Session的路由套中间件 Route::middleware([ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, ])->group(function () { Route::get('/test', function () { session()->put('user_phone_number', 'some value'); return 'session写入成功'; }); Route::get('/test2', function () { dd(session()->get('user_phone_number')); }); }); });
注意事项
- 如果是前后端分离项目,前端发起请求时必须开启跨域携带Cookie配置,比如使用 axios 时要设置
axios.defaults.withCredentials = true,同时后端跨域配置要允许对应前端域名,不能把允许源设为通配符*,否则浏览器不会传递存储 Session ID 的 Cookie,后端依然无法识别同一用户的连续请求。 - Laravel 设计 API 路由的初衷就是无状态,官方并不推荐在 API 场景下使用 Session,常规 API 鉴权优先选择 Sanctum、Passport 这类 Token 方案,使用 Session 会破坏 API 的无状态特性,后续做分布式部署、多端兼容时会增加额外适配成本。
内容的提问来源于stack exchange,提问作者Pouya Vaghefi
相关产品推荐
相关产品推荐

