# 8.6 Token 使用说明 :::tip 概述 本文档面向 API 对接方:如何获取令牌、如何携带、如何刷新、如何撤销。令牌为 JWT HS256 双令牌(access 2h + refresh 7d),唯一使用下划线命名的响应。 ::: ## 获取令牌(POST /api/login,公开) ```sh curl -X POST http://127.0.0.1:8000/api/login \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"123456","code":"618618","key":""}' ``` ```json { "code": 0, "ok": true, "msg": "操作成功", "data": { "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.…", "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.…", "expires_in": 7200, "token_type": "Bearer" } } ``` ::: warning 命名例外 登录/令牌接口返回 `access_token/refresh_token/expires_in/token_type`(OAuth2 惯例下划线命名)——这是全系统唯一例外,其余接口出入参一律驼峰。 ::: ## 携带令牌调用业务接口 ```sh curl http://127.0.0.1:8000/api/user/page?pageNo=1&pageSize=10 \ -H "Authorization: Bearer " ``` 兼容细节:Bearer 前缀大小写不敏感、可无前缀直接传 token;个别场景支持查询参数 `?token=`(URL 直传)。 ## 刷新令牌(POST /api/oauth2/token,公开) access 过期(收到 code=401)时用 refresh_token 轮换新令牌对: ```sh curl -X POST http://127.0.0.1:8000/api/oauth2/token \ -H "Content-Type: application/json" \ -d '{"grant_type":"refresh_token","refresh_token":""}' ``` ```json { "data": { "access_token": "…", "refresh_token": "…", "expires_in": 7200, "token_type": "Bearer" } } ``` 刷新语义: ```text * 旧 refresh 入黑名单(轮换)——旧 refresh_token 立即作废,必须存新值 * 旧 access 自然过期(不主动拉黑) * 返回同登录格式四字段 * 兼容密码模式:grant_type=password 或无 refresh_token → 复用登录逻辑 ``` ## 撤销与校验 ```text GET /api/logout 登出(当前 access jti 拉黑) DELETE /api/oauth2/remove/:token 撤销指定令牌(登录可用;解析 jti 入黑名单) GET /api/oauth2/check/token 校验令牌有效性(JWT 中间件通过即有效) ``` ## 对接方实现要点 ```text 1. 存储:access 与 refresh 分开存(内存/localStorage);refresh 泄露=账号风险 2. 请求:全部业务请求带 Authorization: Bearer 3. 401 处理:单飞刷新(并发 401 只触发一次 refresh,其余等结果); refresh 失败(1008/401)→ 清令牌 → 跳登录 4. 刷新成功:立即用新令牌对覆盖旧值(旧 refresh 已作废) 5. 时钟偏移:以 expires_in 倒计时提前刷新(如过期前 60s),减少 401 6. 登出:调 /api/logout 后清本地——不调的话令牌有效期内仍可用 ``` ## 令牌状态速查 | 状态 | 表现 | 处理 | |------|------|------| | 有效 | 业务正常 | — | | access 过期 | code=401 | refresh 轮换 | | refresh 过期/已轮换 | code=1 或 1008 | 重新登录 | | 已拉黑(登出/强退) | code=401 | 重新登录(强退的 refresh 也拉黑,无法复活) | | 算法/签名无效 | code=401 | 检查是否跨环境混用 jwt.secret | ## 安全建议 + HTTPS 传输(令牌明文等价于会话) + refresh_token 泄露面最小化(不入 URL、不入日志——后端已脱敏) + 客户端不持久化 access(内存优先);persist refresh 的场景加密存储 + 多端登录场景用在线用户模块管理(forceLogout 双令牌拉黑)