信息发布→ 登录 注册 退出

Laravel如何使用JWT进行用户认证_Laravel集成jwt-auth插件与Token刷新【方法】

发布时间:2026-01-11

点击量:
JWT认证在Laravel中需手动集成tymon/jwt-auth 2.x(社区维护版),配置服务提供者、发布配置、实现JWTSubject接口;登录需校验字段匹配,刷新依赖黑名单与有效期设置;Header格式(Bearer后空格)和Apache重写规则易致验证失败。

JWT 认证在 Laravel 中不是开箱即用的,必须通过 laravel/jwt-auth(已停止维护)或更现代的替代方案(如 tymon/jwt-auth 的社区维护分支 php-jwt/jwt-auth)实现;当前推荐直接使用 laravel/sanctumlaravel/passport,但若项目已依赖 tymon/jwt-auth 且需继续维护,以下操作基于其 2.x 版本(适配 Laravel 9/10)。

安装 tymon/jwt-auth 并配置服务提供者

该包官方主仓库已归档,需使用活跃的 fork 版本。Laravel 9+ 不再自动发现服务提供者,必须手动注册:

  • 执行 composer require "tymon/jwt-auth:2.0.*"(注意:不是原版 jwt-auth,而是社区维护的兼容版本)
  • 运行 php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider" 生成配置文件 config/jwt.php
  • config/app.phpproviders 数组中添加:
    Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
  • app/Providers/AuthServiceProvider.phpboot() 方法中添加:
    JWTAuth::factory()->setUserModel(User::class);

定义登录接口并生成 Token

不能直接调用 JWTAuth::attempt() 而不验证字段——它默认只检查 emailpassword,若你的用户表用的是 username 或其他字段,必须先重写 User 模型的 getJWTIdentifier()getJWTCustomClaims(),否则会返回空 Token 或 "token_not_provided" 错误。

  • 确保 User 模型实现了 Tymon\JWTAuth\Contracts\JWTSubject 接口
  • 登录控制器中使用标准验证逻辑:
    use Tymon\JWTAuth\Facades\JWTAuth;
    

    public function login(Request $request) { $credentials = $request->only('email', 'password'); if (!$token = JWTAuth::attempt($credentials)) { return response()->json(['error' => 'invalid_credentials'], 401); } return response()->json(compact('token')); }

  • 注意:Laravel 10 默认启用严格 CSRF 保护,API 路由需放在 routes

    /api.php
    并确认中间件是 api 组(不含 VerifyCsrfToken

刷新 Token 时必须传入旧 Token 并校验有效期

JWTAuth::refresh() 不会自动从请求头读取 Token,必须显式传递;且刷新失败常见原因不是代码写错,而是 Token 已过期(ttl 过短)或被加入黑名单(blacklist_enabled 为 true 且未正确清除)。

  • 刷新接口示例:
    public function refresh()
    {
        try {
            $newToken = JWTAuth::refresh(); // 自动从 Authorization header 读取 Bearer Token
        } catch (\Exception $e) {
            return response()->json(['error' => 'token_invalid'], 401);
        }
        return response()->json(compact('newToken'));
    }
  • 确保 config/jwt.php'blacklist_enabled' => true,且刷新后旧 Token 被加入黑名单(这是默认行为)
  • 若需延长有效时间,调整 'ttl' => 60(分钟)和 'refresh_ttl' => 20160(14 天),但注意 refresh_ttl 必须 ≥ ttl

中间件验证失败时容易忽略的 Header 格式问题

前端必须在请求头中传入 Authorization: Bearer ,少一个空格、多一个引号、或用了双引号包裹 token,都会导致 token_not_providedtoken_expired 报错,而 Laravel 日志里不会明确提示格式问题。

  • 验证中间件(如 auth:api)底层调用的是 JWTGuard,它依赖 Request::bearerToken() 提取 token
  • 测试时可用 curl 手动验证:
    curl -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." http://localhost:8000/api/user
  • 若用 axios,确保设置:
    axios.defaults.headers.common['Authorization'] = 'Bearer ' + token;
  • Apache 服务器需额外配置,否则 Authorization header 会被丢弃:
    RewriteCond %{HTTP:Authorization} ^(.*)
    RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

JWT 的 stateless 特性意味着所有校验都发生在应用层,没有 session 存储开销,但代价是无法主动使 Token 失效(除非用黑名单),且刷新逻辑必须与前端配合严格对齐——Token 过期时间、刷新窗口、错误重试策略,任何一个环节没对上,用户就会卡在“登录成功却无法访问接口”的状态。

标签:# Session  # 不含  # 任何一个  # 或其他  # 用了  # 而不  # 放在  # 就会  # 这是  # 重写  # 的是  # 接口  # Token  # cURL  # php  # require  # csrf  # 中间件  # axios  # app  # cad  # apache  # composer  # json  # 前端  # js  # laravel  # word  
在线客服
服务热线

服务热线

4008888355

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!