Chào các bạn,

Ở bài  Bài 14 – Component Authentication – xác thực người dùng chúng ta đã cũng tìm hiểu qua Auth component, ở đây mình sẽ giới thiệu về Access Control List(ACL), và trong nội dung bài này sẽ là sử dụng file ini trong CakePHP phù hợp với dự án nhỏ ít user quản lý, còn cách sử dụng đến database cho dự án lớn nhiều user quản lý mình sẽ giới thiệu ở bài sau.

Tham khảo thêm ở đây

Điều kiện:

  • Source code bài mới nhất trong series CakePHP của mình bao gồm cả database.

Bước 1: Cấu hình lại database

Nếu sử dụng database của mình ở bài trước thì hiện tại bảng users đã có 3 rows tồn tại, mình sẽ thêm một column mới với tên là groups với lệnh sau.


ALTER TABLE `users` ADD `groups` VARCHAR(20) NOT NULL DEFAULT 'user' AFTER `date_updated`;

column groups này hiện tại mình cho 3 giá trị nhá admin, user, gold_user mặc định là user.

Khi bạn chạy lệnh sql trên thì cả 3 user đang có đều có quyền là user

Bước 2: Chỉnh sửa phần user trong admin.

Ở phần danh sách /app/View/Users/admin_list.ctp chúng ta sẽ thêm phần hiển thị column groups đó ra. Nội dung table sau khi chỉnh sửa:


<table width="100%" class="table table-striped table-bordered table-hover" id="dataTables-example">
<thead>
<tr>
<th>ID User</th>
<th>Name</th>
<th>Username</th>
<th>Email</th>
<th>Groups</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php foreach($users as $key => $val){
?>
<tr>
<td><?php echo $val['User']['id']?></td>
<td><?php echo $val['User']['name']?></td>
<td><?php echo $val['User']['username']?></td>
<td><?php echo $val['User']['email']?></td>
<td><?php echo $val['User']['groups']?></td>
<td>
<?php echo $this->Html->link('Edit',array('controller'=>'users','action'=>'edit',$val['User']['id']), array('class' => 'btn btn-warning'));
?>
<?php echo $this->Html->link('Del',array('controller'=>'users','action'=>'delete',$val['User']['id']), array('class' => 'btn btn-danger'));
?>
</td>
</tr>
<?php }?>
</tbody>
</table>

Đương nhiên ở phần add và edit user chúng ta sẽ cho lựa chọn groups và lưu vào database(nội dung trong phần download)

Sau khi thay đổi trên hoàn thành các bạn hãy thêm một user mới hoặc chỉnh sửa user đang có sao cho có 3 loại group để mình đăng nhập vào test

Kết quả sau bước trên:

access control list nongdanit cakephp

Bước 3: chỉnh sửa file app/Config/core.php

Mở file này lên và tìm đến đoạn sau và ẩn nó đi.


Configure::write('Acl.classname', 'DbAcl');
Configure::write('Acl.database', 'default');

thêm vào đoạn dưới đây:


Configure::write('Acl.classname', 'IniAcl');

Save lại và tiếp tục mở file app/Config/acl.ini.php

Giải thích 2 khái niệm ARO và ACO nó thường được sử dụng trong phân quyền:

  • ARO: Đối tượng muốn một thứ gì đó (Access Request Object).
  • ACO: Đối tượng mà đối tượng khác muốn (Access Control Object).

Trong file này ta sẽ định nghĩa các ARO và ACO chúng có các thuộc tính sau:

  • groups: tên nhóm ARO.
  • allow: tên của ACO mà ARO có quyền truy cập.
  • deny: tên của ACO mà ARO không có quyền truy cập.

Mình có đoạn sau dùng để phân quyền, copy đoạn sau dán vào cuối file nhá:


[admin]
groups = admin

[user]
groups = user
deny = admin_edit, admin_add, admin_delete, admin_review

[gold_user]
groups = gold_user
deny = admin_delete
[guest]
groups = guest
allow = admin_login, admin_logout

[admin]
allow = admin_login, admin_logout, admin_list, admin_add, admin_edit, admin_index, admin_delete, admin_review

[user]
allow = admin_login, admin_logout, admin_list

[gold_user]
allow = admin_login, admin_logout, admin_list, admin_add, admin_index, admin_edit, admin_review

Tương ứng với 3 loại groups trong database mình thêm 3 group trên.

  • admin có tất cả các quyền: add, edit, list, del…
  • user thì chỉ cho list các quyền còn lại thì chặn
  • gold_user có tất cả các quyền admin nhưn bị chặn quyền xoá đi.

Bước 4: Test phần phân quyền.

Ở đây mình chỉ làm phần kiểm tra xem user đang đăng nhập có groups nào và sử dụng $this->Acl->check() để biết được có quyền hay không, kết quả hàm này sẽ trả về true hoặc false, mình sẽ thông báo ra chứ không làm gì thêm, các bạn tự bổ sung thêm như: chuyển page thông báo gì đó hay logout ra yêu cầu đăng nhập bằng quyền khác chẳng hạn …

Trong beforeFilter của app/Controller/AppController.php thêm vào đoạn sau:


$user = $this->Auth->user();
if(!empty($user["groups"])){
if(($this->Acl->check($user["groups"], $this->params['action']))){
$this->Session->setFlash('You can access','default',array('class'=>"alert alert-success"));
}else{
$this->Session->setFlash('You can not access','default',array('class'=>"alert alert-success"));
}
}

Đăng nhập vào các user đang có để test các quyền nhá. Nếu có thắc mắc các bạn có thể hỏi thêm ở phần comment. Có thể mình làm không đúng cách cho lắm, nếu sai sót xin ý kiến các bạn.

Bài tiếp theo cũng làm phần Access Control List nhưng sử dụng database chứ không dùng ini nữa. Mong các bạn tiếp tục cùng nongdanit

Kết luận

  1. Nếu có thắc mắc gì các bạn để lại comment bên dưới mình sẽ trả lời sớm nhất có thể.
  2. Cảm ơn các bạn đã đọc.

Nongdanit.info
[Cakephp] – Hướng dẫn Access Control List sử dụng INI