必须改用psr-15中间件+显式注入认证服务+独立授权策略,否则报错;需同时安装yiisoft/auth与yiisoft/rbac扩展;配置identityinterface实现类;注册authenticationmiddleware;手动定义并绑定rbac策略;控制器中须构造函数注入identityinterface和policyinterface。

要在 Yii 3.0 中实现用户登录、权限校验和角色控制,必须放弃 Yii::$app->user 和 RBAC 组件的旧式调用,改用 PSR-15 中间件 + 显式注入的认证服务 + 独立授权策略,否则请求会直接抛出 Call to undefined property Yii::$app 或 Service not found in container 错误。
安装认证与授权扩展包
Yii 3.0 不内置 Auth 模块,需手动引入官方维护的独立包:
执行 composer require yiisoft/auth yiisoft/rbac。注意:这两个包必须同时安装,【yiisoft/rbac 单独安装无法工作,它依赖 yiisoft/auth 提供的 IdentityInterface 和 AuthenticationInterface】。
若使用 MySQL 存储权限规则,还需追加 composer require yiisoft/db;若仅用内存策略(如开发调试),可跳过。
配置用户身份提供器(Identity Provider)
这一步定义“谁是用户”以及“如何查用户”:
在 config/common.php 中注册 yii\auth\IdentityInterface 实现类:
IdentityInterface::class => ['class' => App\Identity\UserIdentity::class],
创建 src/Identity/UserIdentity.php,该类必须实现 IdentityInterface 并提供 findIdentityById()、findIdentityByToken() 和 validateCredentials() 方法。不要继承任何 Yii 2.x 的 BaseIdentity——Yii 3.0 没有这个基类。
⚠️ 常见错误:若 validateCredentials() 返回 null 而非 IdentityInterface 实例,登录中间件将静默失败,且无日志提示。
注册认证中间件并挂载到请求栈
Yii 3.0 的认证流程由 PSR-15 中间件驱动,不再靠控制器钩子:
打开 config/web.php,找到 middleware 配置项,在数组开头插入:
new \Yiisoft\Auth\Middleware\AuthenticationMiddleware(),
这行代码必须放在所有路由中间件之前,否则 $request->getAttribute('user') 在后续中间件中始终为 null。
该中间件会自动从请求中提取 token(支持 Cookie、Bearer Token、Query 参数三种方式),调用你配置的 IdentityProvider,并将结果存入 Request 属性。
定义并加载 RBAC 权限规则
Yii 3.0 的 RBAC 不再读取 @app/rbac/ 目录下的 PHP 文件,而是通过容器绑定策略实例:
第一步:创建策略类,例如 src/Rbac/PostAuthorPolicy.php,实现 Yiisoft\Rbac\Contract\PolicyInterface,重写 isAllowed() 方法判断当前用户是否有权操作某资源。
第二步:在 config/common.php 中注册策略:
Rbac\Contract\PolicyInterface::class => ['class' => Rbac\PostAuthorPolicy::class],
第三步:在需要鉴权的中间件或控制器中,显式注入 Rbac\Contract\PolicyInterface 实例,调用 $policy->isAllowed($identity, 'update', 'post') 判断。
注意:Yii 3.0 【不提供默认的数据库迁移来建 auth_item 表】,如需持久化角色与权限,必须手写 SQL 或使用 yiisoft/db-migration 扩展创建对应表结构。
在控制器中获取当前用户并做权限判断
控制器不能再用 Yii::$app->user->isGuest,必须通过构造函数注入:
① 在控制器构造函数声明参数:public function __construct(private IdentityInterface $identity);
② 判断是否已认证:if ($this->identity instanceof IdentityInterface) { /* 已登录 */ };
③ 获取用户 ID:$this->identity->getId();
④ 获取原始凭证数据(如邮箱):$this->identity->getCredential()->getEmail();
⑤ 执行权限检查:$this->policy->isAllowed($this->identity, 'delete', 'comment')。
这五步缺一不可,跳过第①步会导致容器无法解析依赖,抛出 Entry "App\Controller\SiteController" cannot be resolved。











