Laravel 5.5+ 应安装 tymon/jwt-auth:^1.0.2,手动注册服务提供者、发布配置、正确传 Authorization: Bearer token、配置 guard 和中间件,并注意 ttl 与 refresh_ttl 区别及 token 存储安全策略。

composer install jwt-auth 扩展报错 Class 'Tymon\JWTAuth\Providers\LaravelServiceProvider' not found
这是 Laravel 5.5+ 项目里最常遇到的问题:新版 jwt-auth 已不再维护,官方推荐迁移到 tymon/jwt-auth 的 1.0+ 版本,但它的服务提供者路径和配置方式全变了。
实操建议:
- 别再用
composer require tymon/jwt-auth直接装最新版(v2+),它已彻底移除 Laravel 集成,只留核心 token 操作 - Laravel 5.5–8.x 推荐锁死安装
composer require tymon/jwt-auth:^1.0.2 - 安装后必须手动在
config/app.php的providers数组里加:Tymon\JWTAuth\Providers\LaravelServiceProvider::class - 运行
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"生成配置文件,否则jwt.secret不会自动设置
Laravel 中 JWT token 生成后无法验证:payload 为空或 always returns false
常见现象是调用 auth()->attempt() 成功返回 token,但后续用 auth()->check() 或 auth()->user() 总是 null —— 根本不是 token 无效,而是请求头没传对,或中间件没加载。
实操建议:
- 确保前端在请求头里传的是
Authorization: Bearer {token},不是Token、JWT或漏掉Bearer前缀 - Laravel 6+ 默认中间件组改了,要在
app/Http/Kernel.php的$middlewareGroups['api']里确认是否包含\Tymon\JWTAuth\Http\Middleware\Authenticate::class - 如果用了自定义 guard(比如
api),要检查config/auth.php中guards.api.driver是jwt,且providers.users.model指向正确 User 类 - 别在控制器构造函数里调用
auth()->user(),此时 request 还没进 middleware,token 尚未解析
JWT token 过期时间设了 60,为什么实际 1 分钟就失效?
JWT 的过期逻辑不只看 exp 字段,还受 refresh_ttl 和缓存机制影响。尤其当你用 auth()->refresh() 换新 token 时,系统会校验上一个 token 是否仍在「可刷新窗口」内。
实操建议:
-
ttl控制 token 本身有效期(单位:分钟),refresh_ttl控制该 token 能被刷新的最长期限(比如设为 20160 表示 14 天内都可换新) - 修改
config/jwt.php后,必须运行php artisan config:clear,Laravel 不会自动重载 JWT 配置 - 开发时可用
dd(auth()->payload())查看当前 token 解析出的exp时间戳,对比服务器时间,排除时区偏差 - 别依赖前端传来的
exp,JWT 的过期判断完全由服务端根据签发时间 +ttl计算,前端改不了
JWT token 存 localStorage 安全吗?要不要用 HttpOnly Cookie?
存哪不决定安全性,决定的是攻击面。localStorage 可被 XSS 读取;Cookie 若没设 HttpOnly + Secure + Samesite=Strict,一样会被窃取。
实操建议:
- 纯 SPA(如 Vue/React)项目,token 必须存在 JS 可访问的地方(localStorage/sessionStorage),这时重点应放在防 XSS:输入过滤、CSP 策略、避免 innerHTML 拼接用户数据
- 如果是传统服务端渲染(Blade + Laravel),优先用
HttpOnlyCookie 存 token,配合withCredentials: true发送请求,能天然防 XSS 盗 token - JWT 本身不加密,只是签名,所以敏感字段(如权限列表)不要塞进 payload;真正鉴权必须查数据库或 Redis 缓存
- 别为了“更安全”把 token 存 sessionStorage——关页面就登出,体验断层,反而促使用户写密码到记事本
JWT 的麻烦不在安装或配置,而在它把状态判断从服务端推给了客户端。一旦你开始手动解析 payload、自己比对 role 字段、跳过中间件直接查 auth()->id(),就等于在绕开框架的安全水位线。









