2018-08-27 23:49:01 2116次浏览 4条回答 1 悬赏 10 金钱

应用中的admin模块用于后台管理,admin模块的用户不同于前台的用户,admin模块配置了另外一个authManger组件。配置文件如下:

return [
        'id' => 'app',
        .......
        'components' => [
                'user' => [
                        'identityClass' => 'common\models\User',
                        'enableAutoLogin' => true,
                        'identityCookie' => ['name' => '_identity-app', 'httpOnly' => true],
                ],
                'authManager' => [
                        ......//app中的authMangager配置
                ],
                'errorHandler' => [
                        'errorAction' => 'site/error',
                ],
        ],
        'modules' => [
                'admin' => [
                        'class' => 'mp\modules\admin\Module',
                        'aliases' => [
                                '@module' => '@app/modules/admin',
                        ],
                        'defaultRoute' => 'site',
                        'components' => [
                                'user' => [
                                        'class' => 'yii\web\User',
                                        'identityClass' => 'common\models\Staff',
                                        'idParam' => '__admin_id',
                                        'enableAutoLogin' => false,
                                        'loginUrl' => '/admin/site/login',
                                ],
                                'errorHandler' => [
                                        'class' => 'yii\web\ErrorHandler',
                                        'errorAction' => '/admin/site/error',
                                ],
                                'authManager' => [
                                        'class' => 'yii\rbac\DbManager',
                                        ......//admin模块中的authManager配置
                                ],
                        ],
                ],
        ],
        'params' => $params,
];`

这样配置后,在admin模块检验权限的时候,还是使用了app层配置的那个authManager,怎样才能让admin模块中的代码使用模块自己的authManager呢?
同样的,errorhandler也有一样的问题,该如何解决

补充于 2018-08-29 23:00

的方法是可行的。也找到了其他方法可以不用再模块中替换应用的组件。
研究了一下源代码发现AccessControl在调用User组件的can方法时,如果user组件的$accessChecker属性,如果为空就使用应用的authManager组件,因此,只要设置user组件的这个属性就可以了。于是配置代码改成:
`

    'modules' => [
            'admin' => [
                    'class' => 'mp\modules\admin\Module',
                    'aliases' => [
                            '@module' => '@app/modules/admin',
                    ],
                    'defaultRoute' => 'site',
                    'components' => [
                            'user' => [
                                    'class' => 'yii\web\User',
                                    'identityClass' => 'common\models\Staff',
                                    'idParam' => '__admin_id',
                                    'enableAutoLogin' => false,
                                    'loginUrl' => '/admin/site/login',
                                    'accessChecker' => 'yii\rbac\DbManager',
                            ],
                            'errorHandler' => [
                                    'class' => 'yii\web\ErrorHandler',
                                    'errorAction' => '/admin/site/error',
                            ],
                    ],
            ],
    ],

这样修改后就可以工作了,但是存在一个问题是accessChecker的配置只能通过字符串类名初始化一个默认的组件。问题出在User组件init时是判断is_string才使用Yii::createObject方法创建accessChecker属性的,如果需要让这个属性支持配置数组。需要修改User组件的init方法代码如下:
// if (!empty($this->accessChecker) && is_string($this->accessChecker)) {

    if (!empty($this->accessChecker) && (is_string($this->accessChecker) || is_array($this->accessChecker)) {
        $this->accessChecker = Yii::createObject($this->accessChecker);
    }

或者更进一步,改成这种形式,除了支持通过类名配置和数组配置外还能引用其他已经定义的组件。 if (!empty($this->accessChecker)) {

            $this->accessChecker = Instance::ensure($this->accessChecker, BaseManager::className());
    }

// if (!empty($this->accessChecker) && is_string($this->accessChecker)) {
// $this->accessChecker = Yii::createObject($this->accessChecker);
// }
`
不过很遗憾这个办法只能支持引用应用的组件而不能引用自己模块的组件。

  • 回答于 2018-08-28 07:58 举报
    4 条回复
    回复于 2018-08-28 09:44 回复

    和这个问题中的场景不一样,这个问题里面是同一个项目下的不同应用使用不同的authManager。而我的场景是同一个项目下同一个应用下面的应用和应用的子模块之间使用不同的authManager

    回复于 2018-08-28 11:25 回复

    看你的问题阐述,个人理解是前后台用不同的authManager,是这意思不,如果是那我给你的链接足够你解决你的问题

    回复于 2018-08-28 14:47 回复

    是前后台,但是和你的例子不同的是,我这里前后台在同一个应用里面,后台作为整个应用的一个模块存在而不是一个独立的应用

    回复于 2018-08-28 14:50 回复

    那不就是你需要自己配两套权限管理嘛,意思都是一样的,你把问题想复杂了

  • 回答于 2018-08-29 09:44 举报

    按照你上面的配置,应用内会出现两个 authManager 实例:一个在应用内,通过 Yii::$app->authManager 可访问;另一个在 admin 模块内,通过 Yii::$app->admin->authManager 可访问。通常用来判断权限的Yii::$app->user->can()方法使用的是第一个 authManager.

    若想在 admin 模块内指定使用 admin 模块内的 authManager, 需要在模块内的 init() 内将应用内的 authManager 替换掉,例如:

    // in admin Module 
    
    public function init()
    {
        parent::init();
        
        \Yii::$app->set('authManager', $this->get('authManager'));
    }
    

    error handler 不工作的原因和 authManager 类似,但稍微有些不同,具体可参考: https://www.yiiframework.com/forum/index.php/topic/74234-how-to-load-an-errorhandler-in-a-module/

  • 回答于 2018-08-30 09:40 举报

    但是存在一个问题是accessChecker的配置只能通过字符串类名初始化一个默认的组件。

    ...

    不过很遗憾这个办法只能支持引用应用的组件而不能引用自己模块的组件。

    yii\web\User::accessChecker 的类型是 yii\rbac\CheckAccessInterface, 如果你想通过配置 accessChecker 的办法实现,直接将其值设置成 admin 模块的 authManager 即可:

    'user' => [
        'accessChecker' => Yii::$app->admin->authManager,
    ],
    
  • 回答于 2018-08-30 15:44 举报

    你这个可以自己另外写一个authManager,然后在这个authManager里做判断决定使用什么方法

您需要登录后才可以回答。登录 | 立即注册
wuyan
试用期

wuyan

注册时间:2018-08-27
最后登录:2018-09-25
在线时长:1小时49分
  • 粉丝0
  • 金钱15
  • 威望0
  • 积分25

热门问题