Phân quyền với RBAC trong Yii2 Framework (P10)

Tiếp tục phần này như đã hứa, tại hạ sẽ trình làng với bạn bè đồng dev về phân quyền với RBAC trong Yii2 Framework. Cái gì thì cũng phải có trên có dưới thế nên trong ứng dụng cũng vậy, cũng cần phải có quyền nọ quyền kia không thì loạn hết ứng dụng bạn bè ạ =)). Mặc dù những đồng đội đồng dev hoàn toàn có thể làm chay mấy phần kiểu dạng phân quyền trong ứng dụng, nhưng nếu đã có tương hỗ thì tội gì không dùng nhỉ .

RBAC là gì ?

RBAC hay Role Based Access Control là module được cung cấp để kiểm soát truy cập của người dùng dựa trên vai trò. Đây là một phương pháp có thể thay thế Điều khiển truy cập tùy quyền (discretionary access control – DAC) và Điều khiển truy cập bắt buộc (mandatory access control – MAC).

Yii tiến hành RBAC theo quy mô NIST RBAC. Nó cung ứng tính năng RBAC trải qua thành phần ứng dụng authManager. Sử dụng RBAC tương quan đến hai phần việc làm. Phần tiên phong là kiến thiết xây dựng tài liệu chuyển nhượng ủy quyền RBAC và phần thứ hai là sử dụng tài liệu chuyển nhượng ủy quyền để thực thi kiểm tra quyền truy vấn ở những nơi thiết yếu .

Một vai trò đại diện cho một tập hợp các quyền (ví dụ: tạo bài đăng, cập nhật bài đăng). Một vai trò có thể được chỉ định cho một hoặc nhiều người dùng. Để kiểm tra xem người dùng có quyền được chỉ định hay không.

Liên kết với mỗi vai trò hoặc quyền hoàn toàn có thể có một rule. Rule đại diện thay mặt cho một đoạn mã sẽ được thực thi trong quy trình kiểm tra quyền truy vấn để xác lập xem vai trò hoặc quyền tương ứng có vận dụng cho người dùng hiện tại hay không. Ví dụ : quyền ” update bài đăng ” hoàn toàn có thể có rule kiểm tra xem người dùng hiện tại có phải là người tạo bài đăng hay không. Trong quy trình kiểm tra quyền truy vấn, nếu người dùng KHÔNG phải là người tạo bài đăng, họ sẽ được coi là không có quyền ” update bài đăng ” .

Cấu hình RBAC

Trước khi bắt đầu xác định việc ủy quyền và thực hiện kiểm tra quyền truy cập, các đồng dev cần định cấu hình thành phần ứng dụng authManager . Yii cung cấp hai loại trình quản lý ủy quyền: yii \ rbac \ PhpManager và yii \ rbac \ DbManager . PhpManager sử dụng tệp tập lệnh PHP để lưu trữ dữ liệu ủy quyền, trong khi DbManager lưu trữ dữ liệu ủy quyền trong cơ sở dữ liệu. Các đồng dev có thể cân nhắc sử dụng PhpManager nếu ứng dụng không yêu cầu quản lý vai trò và quyền cần tùy chỉnh được.

Sử dụng PhpManager

Đoạn mã sau cho biết cách đặt cấu hình authManager trong cấu hình ứng dụng bằng lớp yii \ rbac \ PhpManager, các đồng dev cài đặt trong common/config/main.php như sau:

return [
    // ...
    'components' => [
        'authManager' => [
            'class' => 'yii\rbac\PhpManager',
        ],
        // ...
    ],
];

Các authManager bây giờ có thể được truy cập thông qua \Yii::$app->authManager.

Theo mặc định, yii \ rbac \ PhpManager lưu trữ dữ liệu RBAC bằng các tệp trong thư mục @app/rbac. Đảm bảo rằng thư mục và tất cả các tệp trong đó có thể ghi được.

Sử dụng DbManager

Đoạn mã sau đây cho thấy cách đặt cấu hình authManagertrong cấu hình ứng dụng bằng lớp yii \ rbac \ DbManager :

return [
    // ...
    'components' => [
        'authManager' => [
            'class' => 'yii\rbac\DbManager',
            // uncomment if you want to cache RBAC items hierarchy
            // 'cache' => 'cache',
        ],
        // ...
    ],
];

DbManager sử dụng 4 bảng cơ sở dữ liệu để lưu trữ dữ liệu của nó:

  • itemTable : bảng lưu trữ các mục ủy quyền. Mặc định là “auth_item”.

  • itemChildTable : bảng lưu trữ phân cấp mục ủy quyền. Mặc định là “auth_item_child”.

  • assignmentTable : bảng lưu trữ các quyền được gán. Mặc định là “auth_assignment”.

  • ruleTable : bảng lưu trữ các luật hay quy tắc. Mặc định là “auth_rule”.

Trước khi có thể tiếp tục, các đồng dev cần tạo các bảng đó trong cơ sở dữ liệu. Để làm điều này, các đồng dev có thể sử dụng câu lệnh dưới đây để chạy các file migration trong rbac(Phần migration tại hạ sẽ có bài viết ngay sau phần này nhé laugh):

yii rbac

yii rbac

OK, vậy là là đã 4 bảng trong database rồi nhé

yii2 rbac

Tiếp tục để phân quyền qua RBAC, các đồng dev làm theo trình tự sau:

1. Đinh nghĩa những vai trò và những quyền thiết yếu .

2. Thiết lập các mối quan hệ giữa quyền và vai trò.

3. Định nghĩa những quy tắc hay luật
4. Liên kết những luật với vai trò và quyền
5. Gán vai trò cho người dùng

Ví dụ tại hạ có 2 vai trò là AdminAuthor, Admin sẽ có toàn quyền của Author và thêm quyền update bài viết và Author thì chỉ có quyền tạo bài viết. Tại hạ tiếp tục sử dụng migration để chạy migrate tạo ra các quyền và vai trò cần thiết như sau

– Đầu tiên sẽ tạo file migration bằng cách chạy lệnh sau trong command line :

./yii migrate/create init_rbac

Sau đó nhấn y để tạo

yii2 rbac

OK thành công, tiếp tục chạy câu lệnh migrate để thực thi chèn dữ liệu vào database

./yii migrate

yii2 rbac

Kiểm tra database đã có tài liệu là được

yii2 rbac

Để gán vai trò cho user, tại hạ sẽ demo ở bước ĐK trong hàm signup của frontend \ models \ SignupForm như sau :

public function signup()
{
    if ($this->validate()) {
        $user = new User();
        $user->username = $this->username;
        $user->email = $this->email;
        $user->setPassword($this->password);
        $user->generateAuthKey();
        $user->save(false);

        // the following three lines were added:
        $auth = \Yii::$app->authManager;
        $authorRole = $auth->getRole('author');
        $auth->assign($authorRole, $user->getId());

        return $user;
    }

    return null;
}

Như vậy các user mới đăng ký sẽ được gán cho vai trò là Author và chỉ có quyền đựợc tạo bài viết.

Để kiểm tra quyền truy vấn trải qua tài liệu đã có bên trên, tại hạ sẽ sử dụng \ Yii :: $ app -> user -> can để check. Ví dụ, tại hạ muốn check xem user này có quyền sửa bài viết không

if (\Yii::$app->user->can('updatePost')) {
    // update post
}

Ngoài ra, còn sử dụng RBAC được trong AccessControl như sau:

public function behaviors()
{
    return [
        'access' => [
            'class' => AccessControl::class,
            'rules' => [
                [
                    'allow' => true,
                    'actions' => ['create'],
                    'roles' => ['createPost'],
                ],
                [
                    'allow' => true,
                    'actions' => ['update'],
                    'roles' => ['updatePost'],
                ],
            ],
        ],
    ];
}

Với phần sử dụng PhpManager thì các đồng dev làm như sau:

– Đầu tiên các đồng dev tạo cho tại hạ 1 controller là RbacController trong console để tí chạy command cho phần RBAC

authManager;
        $auth->removeAll();
        
        // add "createPost" permission
        $createPost = $auth->createPermission('createPost');
        $createPost->description = 'Create a post';
        $auth->add($createPost);

        // add "updatePost" permission
        $updatePost = $auth->createPermission('updatePost');
        $updatePost->description = 'Update post';
        $auth->add($updatePost);

        // add "author" role and give this role the "createPost" permission
        $author = $auth->createRole('author');
        $auth->add($author);
        $auth->addChild($author, $createPost);

        // add "admin" role and give this role the "updatePost" permission
        // as well as the permissions of the "author" role
        $admin = $auth->createRole('admin');
        $auth->add($admin);
        $auth->addChild($admin, $updatePost);
        $auth->addChild($admin, $author);

        // Assign roles to users. 1 and 2 are IDs returned by IdentityInterface::getId()
        // usually implemented in your User model.
        $auth->assign($author, 2);
        $auth->assign($admin, 1);
    }
}

Sau đó chạy command

./yii rbac/init

Tiếp tục trong thư mục console, tạo 1 thư mục rbac và tạo file console \ rbac \ UserGroupRule. php trong thư mục rbac vừa tạo

namespace console\rbac;

use Yii;
use yii\rbac\Rule;

/**
 * Checks if user group matches
 */
class UserGroupRule extends Rule
{
    public $name = 'userGroup';

    public function execute($user, $item, $params)
    {
        if (!Yii::$app->user->isGuest) {
            $group = Yii::$app->user->identity->group;
            if ($item->name === 'admin') {
                return $group == 1;
            } elseif ($item->name === 'author') {
                return $group == 1 || $group == 2;
            }
        }
        return false;
    }
}

Cuối cùng sửa lại config trong common/main.php như sau:

return [
    // ...
    'components' => [
        'authManager' => [
            'class' => 'yii\rbac\PhpManager',
            'defaultRoles' => ['admin', 'author'],
        ],
        // ...
    ],
];

Và sử dụng Yii :: $ app -> user -> identity -> group để kiểm tra, nếu là 1 thì là vai trò admin còn lại thì là vai trò group .

Tổng kết 

Bài viết chỉ nêu ra phương pháp hoạt động giải trí phân quyền của RBAC trong 2 trường hơp sử dụng với tài liệu và không sử dụng tài liệu. Ngoài việc sử dụng RBAC ra những bạn bè đồng dev hoàn toàn có thể tự build cho mình 1 mạng lưới hệ thống phân quyền riêng của mình để hoàn toàn có thể sử dụng thuận tiện hơn. Bài viết còn nhiều thiếu sót mong bạn bè bỏ quá cho tại hạ .