yii框架默认不支持jwt鉴权,因httpbearerauth仅提取token字符串而不解析校验;必须继承并重写authenticate()方法,用jwt扩展验证签名与声明,并在findidentitybyaccesstoken()中解析payload查用户,最后调用loginbyaccesstoken()激活用户身份。

Yii 框架本身不验证 JWT Token,必须靠扩展 + 自定义行为完成鉴权;直接用 HttpBearerAuth 只能校验 Basic 或 Bearer 原始 token 字符串,对 JWT 无效。
为什么 HttpBearerAuth 默认不适用于 JWT
它只负责从 Authorization 请求头提取 token 字符串,不解析、不解码、不校验签名和过期时间。如果你没替换它的 authenticate() 逻辑,它会把 JWT 当成任意字符串传给 findIdentityByAccessToken(),而该方法默认只查数据库字段,根本不会调用 JWT 解析库。
- 现象:前端传了
Authorization: Bearer eyJ0eXAiOiJKV1Qi...,后端返回 401 却无日志提示原因 - 根源:
HttpBearerAuth的默认实现里没有 JWT 校验步骤,findIdentityByAccessToken()也没被改写去解析 payload - 后果:token 过期、篡改、格式错误都会静默失败,调试时只能靠抓包看 header 是否送达、再手动 decode 调试
必须自定义 JwtHttpBearerAuth 类
不能直接用 yii\filters\auth\HttpBearerAuth,得继承它并重写 authenticate() 方法,在里面调用 JWT 扩展(如 lcobucci/jwt 或 sizeg/yii2-jwt)做完整校验。
- 关键动作:从 header 提取 token → 用
Parser::parse()解析 → 用Signer和密钥验证签名 → 用ValidationData校验exp/nbf等声明 - 成功后,必须调用
\Yii::$app->user->loginByAccessToken($payload->sub, $type)或类似逻辑,否则\Yii::$app->user->identity仍是 null - 别在
authenticate()里 throw 异常,应返回null(认证失败)或new \yii\web\Identity实例(成功),让框架统一处理 401
findIdentityByAccessToken() 必须适配 JWT payload
这个方法是 Yii 用户系统和 JWT 衔接的唯一入口,它接收的是原始 token 字符串,但你要在里面做 JWT 解析,并用 payload 中的用户标识(如 sub、uid 或 username)查库。
- 示例逻辑:
$payload = (new Parser())->parse($token); return static::findOne(['id' => $payload->sub]); - 注意:不要在该方法里做签名校验——那属于认证行为层职责,重复校验既低效又易出错
- 如果 payload 里存的是 username,记得用
static::findByUsername($payload->username),而不是硬编码字段名 - 密钥必须从配置读:
\Yii::$app->params['jwtKey'],别写死在方法里
JWT 异常必须显式捕获并转成 HTTP 401
JWT 扩展抛出的异常(如 Lcobucci\JWT\Exception 或 sizeg\jwt\exceptions\JwtException)不会被 Yii 的 errorHandler 自动映射为 401,会导致 500 错误或空白响应。
- 在自定义认证类的
authenticate()中,用try/catch包住 JWT 解析逻辑 - 捕获到异常后,直接 return null,不要
throw new UnauthorizedHttpException()—— 让框架自己触发 401 - 若需记录日志,加一行
\Yii::error("JWT validation failed: " . $e->getMessage(), __METHOD__); - 别依赖
errorHandler的errorAction处理这类异常,它只管未被捕获的顶层异常
最易被忽略的一点:JWT 是无状态的,但 \Yii::$app->user 默认依赖 session。哪怕 token 验证通过、用户查出来了,如果不调用 loginByAccessToken(),后续所有 \Yii::$app->user->identity 都是 null——权限判断、日志记录、行为钩子全失效。











