Laravel 5.5 中 JWT 身份验证必须用 tymon/jwt-auth 的 1.0.0-rc.2 或 dev-develop 分支,不能用稳定版 0.x;php artisan jwt:secret 是强制步骤,漏掉就无法签发有效 token。

直接说结论:Laravel 5.5 中 JWT 身份验证必须用 tymon/jwt-auth 的 1.0.0-rc.2 或 dev-develop 分支,不能用稳定版 0.x;php artisan jwt:secret 是强制步骤,漏掉就无法签发有效 token。
为什么不能装 tymon/jwt-auth 的最新稳定版?
Laravel 5.5 的 Auth guard 机制和容器绑定方式与旧版 JWT 不兼容。如果你执行 composer require tymon/jwt-auth(默认拉取 0.5.x),会遇到:
-
Target class [tymon.jwt.provider] does not exist—— 服务提供者注册失败 -
Call to undefined method Illuminate\Auth\RequestGuard::once()—— guard 缺少必要方法 - 即使强行绕过,
auth('api')->attempt()返回null且无报错
正确做法是明确指定适配版本:composer require tymon/jwt-auth:1.0.0-rc.2 或 composer require tymon/jwt-auth:dev-develop --prefer-source。
php artisan jwt:secret 必须在发布配置后立即执行
这个命令不是“可选优化”,它会向 .env 写入 JWT_SECRET=...,而 config/jwt.php 中的 'secret' => env('JWT_SECRET') 依赖它。常见错误包括:
- 先改了
config/auth.php再运行jwt:secret→ token 签名失败,所有请求返回 401 - 用
php artisan jwt:generate(旧版命令)→ 报错退出,且不生成密钥 - 手动在
.env里写JWT_SECRET=xxx但没清 config cache → 仍读取默认空字符串
执行完后务必运行:php artisan config:clear。
Auth guard 配置必须改对三处,缺一不可
只改 config/auth.php 的 guards.api.driver 不够。还要确认:
-
guards.api.provider指向的 provider 名称(如users)必须与providers数组中定义的一致 -
providers.users.model必须指向已实现JWTSubject接口的模型(通常是App\User) -
defaults.guard建议设为api,否则auth()->user()默认走 web guard,拿不到 JWT 用户
典型安全风险:如果 providers.users.model 指向一个没实现 getJWTIdentifier() 的模型,auth('api')->attempt() 会静默失败,前端只看到 401,日志里却无异常。
用户模型必须实现 JWTSubject,且 getJWTIdentifier() 不能返回 null
很多开发者复制代码时忽略模型主键类型。例如:
- 用 UUID 作主键但没重写
getJWTIdentifier()→ 返回null→ token payload 的sub字段为空 → 验证时解析失败 - 表名不是
users却没改protected $table = 'admin_users'→ 查询时找错表,凭据匹配永远失败 - 密码字段不是
password(比如叫pwd_hash)但没在模型里覆盖$hidden和验证逻辑 → token 能生成,但后续auth('api')->user()可能暴露敏感字段
最简安全实现就是原样复制 getJWTIdentifier() 返回 $this->getKey(),并确保该值非空、可序列化。
真正容易被忽略的是:JWT 密钥一旦写入 .env 就不该再提交到 Git;每次部署新环境都必须重新运行 jwt:secret 并确保 config:clear 生效——否则你调试半天的 401,可能只是缓存里还躺着上一台机器的密钥。


















