直接使用 yii\filters\auth\HttpBearerAuth 可自动提取 Bearer Token 并调用 findIdentityByAccessToken(),需确保 user 组件配置正确、禁用 session、模型实现该方法;Apache/Nginx 需透传 Authorization 头,cURL 和前端注意格式与 CORS;方法内须自行校验 token 有效性、过期及类型,并添加调试日志。

直接用 yii\filters\auth\HttpBearerAuth,它会自动从 Authorization 请求头提取 Bearer Token 并调用 findIdentityByAccessToken()。别手动读 $_SERVER['HTTP_AUTHORIZATION']——那样绕过框架认证链,权限、日志、行为钩子全失效。
HttpBearerAuth 怎么配才生效
必须确保三件事同时成立,否则永远 401 且无提示:
-
user组件已配置,且identityClass指向实现了IdentityInterface的模型(比如User) -
user组件中启用了enableSession => false(API 场景下 session 不该启用) - 模型里必须定义
findIdentityByAccessToken($token, $type = null)方法,且返回非 null 对象;方法内部要自己查库或 Redis 校验 token 是否存在、未过期、类型匹配
为什么 Authorization 头取不到 token
常见原因不是代码写错,而是环境或请求本身不达标:
- Apache 服务器默认会过滤掉带
Authorization的 header,需在.htaccess或虚拟主机配置里加:RewriteCond %{HTTP:Authorization} ^(.*)$+RewriteRule .* - [e=HTTP_AUTHORIZATION:%1] - Nginx 需显式透传:
proxy_set_header Authorization $http_authorization; - cURL 测试时漏了空格:
-H "Authorization: Bearer xxx"错写成"Authorization:Bearer xxx"(冒号后必须有空格) - 前端发请求没设
credentials: 'include'或没加Access-Control-Allow-Headers: Authorization响应头,导致浏览器预检失败,实际请求根本没发出
findIdentityByAccessToken 里要注意什么
这个方法是 token 校验的唯一入口,框架不帮你做任何业务逻辑:
-
$type参数默认为null,但你可以用它区分场景,比如前端用'web'、App 用'mobile',然后在数据库里加字段约束 - token 值不会被自动清理,也不会自动校验过期时间——你得自己查
expires_at字段或解析 JWT payload - 别直接用
findOne(['access_token' => $token])就完事,至少加个andWhere(['>=', 'expires_at', time()]) - 如果 token 存 Redis,注意 key 设计要防碰撞,比如
auth:token:{sha256($token)},避免明文 token 被扫出
最容易被忽略的是:token 校验失败时,findIdentityByAccessToken 返回 null,框架就静默返回 401 —— 没日志、没 trace、没上下文。上线前务必在该方法开头加一行 Yii::debug("token lookup: {$token}", __METHOD__);,不然排查起来就是盲人摸象。


















