Laravel中Session不可用的首要原因是驱动配置错误或中间件未加载:SESSION_DRIVER不匹配、file驱动目录无写权限、redis/database驱动未正确配置或迁移、API路由缺失web中间件,以及误用$_SESSION导致加密和GC失效。

Session 在 Laravel 里默认就可用,但如果你调用 session('key') 拿不到值、request()->session()->put() 写不进数据,大概率不是代码写错了,而是驱动没配对或中间件没加载。
SESSION_DRIVER 配不匹配是头号故障点
本地开发用 file 驱动(默认),但部署到容器或无写入权限的服务器时,storage/framework/sessions 目录可能不可写——这时 session 表面“没报错”,实则每次请求都新建一个空会话,数据根本存不住。
- 检查
.env中的SESSION_DRIVER=redis是否和config/session.php里的'driver' => env('SESSION_DRIVER', 'file')一致 -
redis驱动要求 PHP 已启用phpredis扩展,且REDIS_HOST可连;database驱动必须先运行php artisan session:table && php artisan migrate -
array驱动只在 PHPUnit 测试中安全,它不持久化,每次请求重置——上线环境留着等于关掉 session
别直接操作 $_SESSION,否则加密和 GC 全失效
手动改 $_SESSION['key'] = 'value' 看似能用,但会绕过 Laravel 的序列化、加密、垃圾回收逻辑,导致 flash 数据丢失、跨请求取不到值,甚至触发 Serialization of closure is not allowed 错误。
- 存:用
session(['key' => 'value'])或$request->session()->put('key', 'value') - 取:用
session('key', 'default')(带默认值防 null)、$request->session()->get('key') - 删:用
session()->forget('key'),不是unset($_SESSION['key']) - 闪存:必须用
session()->flash('msg', 'done'),put+forget模拟不了它的“仅下一次有效”语义
API 路由没 session?是因为缺 'web' 中间件
Laravel 的 API 路由组默认不加载 StartSession 中间件,所以即使你写了 session('user_id'),也永远是空的——这不是 bug,是设计。
- 需要 session 的 API 接口(比如调试用、或混合式前端),必须显式加中间件:
->middleware('web') - 检查
app/Http/Kernel.php中$middlewareGroups['web'],确保\Illuminate\Session\Middleware\StartSession::class在你自定义中间件之前 - 如果某个中间件提前
throw异常或返回响应(比如权限拦截),StartSession的写入逻辑就被跳过了,session 不会落盘
过期时间不是 lifetime 说了算
SESSION_LIFETIME=120 意味着“用户 120 分钟没活动就过期”,但实际失效时间还取决于 driver:
-
file驱动依赖 PHP 的 GC 概率触发,可能让 session 提前消失(尤其低流量项目) -
redis驱动严格按 TTL 过期,但若 Redis 实例重启且没开启持久化,所有 session 就丢了 -
database驱动靠定时任务清理过期记录,Laravel 默认没开自动清理,得自己跑php artisan schedule:run或加 cron -
expire_on_close=true会让 session 在浏览器关闭后立即失效,忽略lifetime,适合敏感操作场景
最易被忽略的是中间件顺序和 driver 的 GC 行为——它们不报错,只静默丢数据。上线前务必在目标环境验证 session 写入与跨请求读取是否真实生效,别只信本地 file 驱动的表现。


















