laravel session 存不进 redis 的根本原因是未连上 redis 或 redis 配置未生效,导致静默退化为 file 驱动;database 驱动秒登出主因是 sessions 表结构错误或未迁移;生产环境禁用 file 驱动以防负载均衡失效;session_domain、连接配置与 ttl 是三大关键易错点。

Session 存不进 Redis,SESSION_DRIVER=redis 没反应
根本原因通常是 Laravel 没连上 Redis,或者 config/database.php 里 redis 配置没生效。Laravel 的 Session 不会报错提示连接失败,而是静默退化到 file 驱动,导致你以为配置成功了,其实还是写本地文件。
实操建议:
- 先确认
phpredis扩展已启用(php -m | grep redis),不是只装了composer require predis/predis - 检查
.env中REDIS_HOST、REDIS_PORT是否指向真实服务(Docker 环境别写localhost,改用redis容器名) - 运行
php artisan tinker,手动试连:Redis::connection()->ping(),看是否抛出异常 -
config/session.php中的connection键默认是null,若用了非默认 Redis 连接(比如叫cache),得显式设为'connection' => 'cache'
SESSION_DRIVER=database 为什么登录后秒登出
常见于没跑迁移或表结构不对。Laravel 的 database Session 驱动依赖 sessions 表,但这个表必须有 id(主键)、user_id、ip_address、user_agent、payload、last_activity 字段,且 id 必须是 VARCHAR(255) 类型 —— 如果你手建表时用了 INT 或 UUID 主键,Session 就会写不进去,后续请求查不到 session,自然登出。
实操建议:
- 别手建表,直接执行
php artisan session:table再php artisan migrate - 检查表字符集:MySQL 8.0+ 默认
utf8mb4_0900_as_cs,但 Laravel 要求utf8mb4_unicode_ci,否则payload字段插入可能截断 - 如果用了多数据库连接,确认
session表建在SESSION_CONNECTION指定的连接上(默认是config('database.default'))
生产环境该不该用 file 驱动
能用,但仅限单机部署且无自动扩缩容场景。一旦上负载均衡或多实例,file 驱动会让用户在 A 实例登录,B 实例就找不到 session,直接跳登录页 —— 这不是 Bug,是设计如此。
实操建议:
- 哪怕只有一台服务器,也建议换
redis或database:启动快、清理方便、避免磁盘写满 - 用
redis时注意设置SESSION_LIFETIME(对应lifetime配置项),它控制的是 Redis key 的 TTL,不是 Cookie 过期时间;后者由SESSION_COOKIE_LIFETIME控制,两者要配合好 - 不要把
SESSION_SECURE_COOKIE设为true却没配 HTTPS,否则浏览器直接拒存 Cookie,整个 session 流程就断了
Cookie 和 Session 数据对不上,Auth::check() 总是 false
最常踩的坑是 SESSION_DOMAIN 配置错误。比如域名是 app.example.com,但 .env 里写了 SESSION_DOMAIN=.example.com(开头多了点),Chrome 会拒绝发送该 Cookie;或者用了 localhost 开发,却设了 SESSION_DOMAIN=localhost,而现代浏览器要求 localhost 的 Cookie domain 必须为空或精确匹配,不能带点。
实操建议:
- 开发时保持
SESSION_DOMAIN为空字符串(''),让浏览器自动推导 - 生产环境填完整域名,如
SESSION_DOMAIN=app.example.com,不要加点前缀 - 检查
SESSION_HTTP_ONLY和SESSION_SAME_SITE:若前端用 JS fetch 带凭据跨域请求,SAME_SITE=Strict会拦截;建议设为Lax或根据接口需求调成None(此时必须同时开SESSION_SECURE_COOKIE)











