繁体   English   中英

yii2拒绝用户在后端登录

[英]yii2 deny user login on backend

我有应用RBAC迁移的yii2高级模板。 我正在尝试学习RBAC并遵循Docs 2.0

我已使用数据库登录,但前端和后端都使用任何帐户登录。 我已经做了2个RBAC角色(管理员,用户),但无法理解或找到如何

限制后端登录非管理员用户角色。

以下是角色的代码。 和数据库条目:

namespace console\controllers;

use Yii;
use yii\console\Controller;

class RbacController extends Controller
{
    public function actionInit()
    {
        $auth = Yii::$app->authManager;

        // add "admin" role
        $admin = $auth->createRole('admin');
        $auth->add($admin);

        // add "user" role
        $user = $auth->createRole('user');
        $auth->add($user);

        $auth->assign($admin, 1);
    }
}

用户表:

admin   admin@gmail.com     20  10  1421197319  1421197319
user    user@gmail.com      10  10  1421198124  1421198124

现行规则:

'rules' => [
    [
        'actions' => ['login', 'error'],
        'allow' => true,
    ],
    [
        'actions' => ['logout', 'index'],
        'allow' => true,
        'roles' => ['@'],
    ],

解决了 - 注意:解决方案不完全是RBAC而是ACF。

经过搜索和咨询,我找到了这个yii2 viki的解决方案

我不清楚RBAC行为,因为我认为它不会让某个角色在某些操作(登录,提交等)之前执行特定任务。

实际上,RBAC会让你做任何尝试,然后检查是否允许,如果不允许则阻止。

在一个房子里有一些庭院销售,你可以自由地在它的前院漫游。 房门/入口前面没有任何防护装置,也没有锁定。 你试图潜入房子,一旦你进入房子,里面有一些保安人员突然阻止你识别自己,他在房屋安全系统中扫描你的信息(数据库中的权限),但找不到你的权利在家里。 他强迫你出局。 这个警卫是RBAC

我需要一个守卫在前门,除非他们被允许,否则他们不会让任何人进入。 这将是ACF。

所以,现在我需要一种方法告诉后端系统特定角色不能事先执行特定操作(即拒绝后端的非管理员登录),这对RBAC是不可能的,因此我们可以使用'matchCallback'使用ACF。

后端规则:

        'rules' => [
            [
                'actions' => ['login'],
                'allow' => true,
            ],
            [
                'actions' => ['logout', 'index'],
                'allow' => true,
                'roles' => ['@'],
                'matchCallback' => function ($rule, $action) {
                    return Yii::$app->user->identity->isAdmin;
                }
            ],
         ]

matchCallback on True允许执行操作,而False拒绝操作。 isAdmin是一个需要在User模型中定义的getter函数。

namespace /common/models/User;

const ROLE_ADMIN = 20;
public function getIsAdmin()
{
    return $this->role == self::ROLE_ADMIN;
}

我在这个yii2 viki的评论中发布了模型的完整工作代码

你们首先登录用户然后检查他的角色,没有必要。 您的LoginForm模型具有getUser()方法,在调用load()validate()之后找到它,并使用authManager检查角色。 像这样的Smth:

    /** @var LoginForm $model */
    $model = Yii::createObject('loginForm');

    if ($model->load(Yii::$app->request->post()) && $model->validate()) {
        /** @var User $user */
        $user = $model->getUser();
        if (!empty($user) && Yii::$app->authManager->checkAccess($user->getId(), 'admin')) {
            // Don't validate twice
            $model->login(false);
            return $this->goBack();
        } else {
            $model->addError('email', 'This user is not authorized for administration');
        }
    }
    return $this->render('login.twig', [
        'model' => $model,
    ]);

您也不想两次validate() LoginForm,因此将$runValidation param添加到login()方法中。

public function login($runValidation = true)
{
    if ($runValidation) {

您应该向控制器添加行为,如下所示:

public function behaviors()
{
    return [
        'access' => [
            'class' => AccessControl::className(),
            'rules' => [
                [
                    'actions' => ['create', 'delete', 'update'],
                    'allow' => true,
                    'roles' => ['admin'],
                ],
                [
                    'actions' => ['index', 'view'],
                    'allow' => true,
                    'roles' => ['user'],
                ],
            ],
        ],
    ];
}

或者这个编辑:(规则允许任何人访问登录但只允许管理员登录并访问索引页面):

public function behaviors()
{
    return [
        'access' => [
            'class' => AccessControl::className(),
            'rules' => [
                [
                    'actions' => ['login'],
                    'allow' => true,
                    'roles' => ['?'],
                ],
                [
                    'actions' => ['index'],
                    'allow' => true,
                    'roles' => ['admin'],
                ],
            ],
        ],
    ];
}

我通过更改后端登录操作实现了此功能。 这是我的代码,我不知道,它是一个完美的解决方案,但它对我有用。

public function actionLogin()
{    
    if (!\Yii::$app->user->isGuest) {
        return $this->goHome();
    }

    $model = new LoginForm();
    if ($model->load(Yii::$app->request->post()) && $model->login()) {
        //check user roles, is user is Admin? 
        if (\Yii::$app->user->can('Admin'))
        {
            // yes he is Admin, so redirect page 
            return $this->goBack();
        }
        else // if he is not an Admin then what :P
        {   // put him out :P Automatically logout. 
            Yii::$app->user->logout();
            // set error on login page. 
            \Yii::$app->getSession()->setFlash('error', 'You are not authorized to login Admin\'s penal.<br /> Please use valid Username & Password.<br />Please contact Administrator for details.');
            //redirect again page to login form.
            return $this->redirect(['site/login']);
        }

    } else {
        return $this->render('login', [
            'model' => $model,
        ]);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM