HttpBearerAuth 生效需三条件:user 组件配置 identityClass 并实现 findIdentityByAccessToken();enableSession = false;该方法返回 IdentityInterface 实例。Authorization 头常被 Web 服务器过滤,需 Apache/Nginx 配置透传;token 应用 security 生成、Redis 存储(带 TTL),校验须查存、比对、验期;CompositeAuth 中 authMethods 顺序影响优先级,findIdentityByAccessToken() 必须通过 $type 区分认证场景。

HttpBearerAuth 怎么配才生效
直接在控制器 behaviors() 里加 HttpBearerAuth::class 不够,它只是“声明支持”,真正起作用要靠三件事同时到位:
- user 组件必须配置
identityClass,且该类实现了findIdentityByAccessToken($token, $type = null) - user 组件需设
enableSession => false(API 场景下 session 无意义,开了反而干扰) -
findIdentityByAccessToken()必须返回一个实现了IdentityInterface的对象,返回null或抛异常都会导致 401,且默认不打日志
常见错误是只写了行为配置,但 User 类里漏了 findIdentityByAccessToken() 方法,或者方法里查数据库时字段名写错(比如用 token 而不是 access_token),结果请求永远 401,连 debug 都没线索。
Authorization 头为什么总取不到
90% 的 401 不是代码问题,是 Web 服务器把 Authorization 头给吃掉了。Yii2 实际读的是 $_SERVER['HTTP_AUTHORIZATION'] 或 Apache 下重写后的 $_SERVER['REDIRECT_HTTP_AUTHORIZATION'],这两个变量必须至少有一个存在。
- Apache:在虚拟主机或
.htaccess加两行:RewriteCond %{HTTP:Authorization} ^(.*)$RewriteRule .* - [e=HTTP_AUTHORIZATION:%1] - Nginx:在
location块里加:proxy_set_header Authorization $http_authorization;proxy_pass_request_headers on; - PHP-FPM 用户还要检查
fastcgi_param是否漏了HTTP_AUTHORIZATION—— 默认不透传
本地用 curl 测试时注意大小写:-H "Authorization: Bearer xxx" 有效,-H "authorization: Bearer xxx" 在某些中间件下会被忽略。
token 怎么生成和校验才算安全
Yii2 不管发 token,只负责验。你得自己在登录接口里生成、返回、存起来,而且不能图省事:
- 别拼接时间戳+用户ID,也别用
md5(time().$id)这种可预测方案 - 用
Yii::$app->security->generateRandomString(32)生成高强度随机字符串 - token 值别存数据库明文字段,推荐存 Redis:
token:{sha256($raw_token)},value 存user_id和过期时间,设 TTL(如 7200 秒) -
findIdentityByAccessToken()里必须做有效性检查:查 Redis、比对 user_id、验证是否过期,缺一不可
很多人只存了 token,忘了删过期的,Redis 里积压几千个僵尸 token,既占内存又拖慢查询。
CompositeAuth 里混用多种认证方式要注意什么
如果同时支持 Bearer、Basic、Query 参数三种方式,用 CompositeAuth 是对的,但顺序和逻辑容易出错:
-
authMethods数组顺序影响执行优先级,建议把最严格的放前面(比如先试 Bearer,再试 QueryParamAuth) - 每个认证方法独立调用
$user->loginByAccessToken(),但loginByAccessToken()内部会统一走findIdentityByAccessToken()—— 所以这个方法里别硬编码判断来源,要用$type参数区分场景(例如$type === 'api'或$type === 'web') - 如果某个方法失败(比如 QueryParamAuth 没找到
access-token参数),CompositeAuth 会自动跳到下一个,不会中断流程;但只要有一个成功,就认为认证通过
最容易被忽略的是 $type 参数——它默认是 null,但你一旦开始区分多端 token(比如 App 用一套、后台用另一套),就必须显式传值,否则所有 token 都混在一起查,权限边界就塌了。


















