Xử lý quyền truy cập trong Controller và View trong CakePHP
Xử lý quyền truy cập trong Controller và View
Khi xây dựng ứng dụng, việc quản lý quyền truy cập là rất quan trọng để đảm bảo an toàn dữ liệu và kiểm soát hành vi người dùng. CakePHP cung cấp các công cụ mạnh mẽ như Authorization Plugin để hỗ trợ xử lý quyền truy cập dễ dàng.

1. Kiểm tra quyền trong Controller
Để kiểm tra quyền trong Controller, bạn cần sử dụng Authorization Component.
a. Cấu hình Authorization Component
Trước tiên, đảm bảo bạn đã tải Authorization.Authorization
trong AppController
:
namespace App\Controller;
use Cake\Controller\Controller;
class AppController extends Controller
{
public function initialize(): void
{
parent::initialize();
$this->loadComponent('Authorization.Authorization');
}
}
b. Kiểm tra quyền trong các hành động (Actions)
Trong các Controller cụ thể, sử dụng các phương thức của Authorization Component để kiểm tra quyền truy cập. Ví dụ:
namespace App\Controller;
use Cake\Http\Exception\ForbiddenException;
class ArticlesController extends AppController
{
public function view($id)
{
$article = $this->Articles->get($id);
// Kiểm tra quyền 'view' với người dùng hiện tại
$this->Authorization->authorize($article, 'view');
$this->set(compact('article'));
}
public function edit($id)
{
$article = $this->Articles->get($id);
// Chỉ cho phép chỉnh sửa nếu người dùng có quyền 'edit'
if (!$this->Authorization->can($article, 'edit')) {
throw new ForbiddenException('Bạn không có quyền chỉnh sửa bài viết này.');
}
if ($this->request->is(['post', 'put'])) {
$article = $this->Articles->patchEntity($article, $this->request->getData());
if ($this->Articles->save($article)) {
$this->Flash->success('Bài viết đã được chỉnh sửa thành công.');
return $this->redirect(['action' => 'index']);
}
$this->Flash->error('Không thể lưu bài viết. Vui lòng thử lại.');
}
$this->set(compact('article'));
}
}
2. Hiển thị quyền trong View
Trong View, bạn có thể tùy chỉnh giao diện dựa trên quyền của người dùng. CakePHP cung cấp Identity
và các phương thức Authorization để kiểm tra quyền.
a. Sử dụng can()
trong View
<?php if ($this->Identity->can('edit', $article)): ?>
<?= $this->Html->link('Chỉnh sửa', ['action' => 'edit', $article->id]) ?>
<?php endif; ?>
b. Kiểm tra vai trò người dùng
Nếu bạn sử dụng vai trò (role) để phân quyền, kiểm tra như sau:
<?php if ($this->Identity->get('role') === 'admin'): ?>
<?= $this->Html->link('Quản lý người dùng', ['controller' => 'Users', 'action' => 'index']) ?>
<?php endif; ?>
3. Tích hợp kiểm tra quyền toàn cục
Để kiểm tra quyền cho tất cả các hành động trong Controller, sử dụng beforeFilter
:
public function beforeFilter(\Cake\Event\EventInterface $event)
{
parent::beforeFilter($event);
if ($this->request->getParam('action') === 'edit') {
$this->Authorization->authorize($this->request);
}
}
4. Xử lý khi không có quyền truy cập
Khi người dùng không có quyền, bạn có thể chuyển hướng hoặc hiển thị thông báo lỗi.
a. Chuyển hướng người dùng
if (!$this->Authorization->can('edit', $article)) {
$this->Flash->error('Bạn không có quyền truy cập.');
return $this->redirect(['action' => 'index']);
}
b. Hiển thị thông báo lỗi
use Cake\Http\Exception\ForbiddenException;
if (!$this->Authorization->can('edit', $article)) {
throw new ForbiddenException('Truy cập bị từ chối.');
}
5. Ví dụ đầy đủ
Controller: ArticlesController.php
namespace App\Controller;
use Cake\Http\Exception\ForbiddenException;
class ArticlesController extends AppController
{
public function index()
{
$articles = $this->paginate($this->Articles);
$this->set(compact('articles'));
}
public function view($id)
{
$article = $this->Articles->get($id);
$this->Authorization->authorize($article, 'view');
$this->set(compact('article'));
}
public function edit($id)
{
$article = $this->Articles->get($id);
if (!$this->Authorization->can($article, 'edit')) {
throw new ForbiddenException('Bạn không có quyền chỉnh sửa bài viết này.');
}
if ($this->request->is(['post', 'put'])) {
$article = $this->Articles->patchEntity($article, $this->request->getData());
if ($this->Articles->save($article)) {
$this->Flash->success('Bài viết đã được cập nhật.');
return $this->redirect(['action' => 'index']);
}
$this->Flash->error('Không thể cập nhật bài viết.');
}
$this->set(compact('article'));
}
}
View: index.php
<h1>Danh sách bài viết</h1>
<table>
<thead>
<tr>
<th>Tiêu đề</th>
<th>Hành động</th>
</tr>
</thead>
<tbody>
<?php foreach ($articles as $article): ?>
<tr>
<td><?= h($article->title) ?></td>
<td>
<?= $this->Html->link('Xem', ['action' => 'view', $article->id]) ?>
<?php if ($this->Identity->can('edit', $article)): ?>
<?= $this->Html->link('Chỉnh sửa', ['action' => 'edit', $article->id]) ?>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
Kết luận
- Trong Controller: Sử dụng
Authorization->authorize()
vàAuthorization->can()
để kiểm tra quyền trước khi xử lý. - Trong View: Sử dụng
Identity->can()
để hiển thị hoặc ẩn các liên kết/hành động dựa trên quyền. - Xử lý các trường hợp không có quyền bằng cách chuyển hướng hoặc thông báo lỗi.

Với hơn 10 năm kinh nghiệm lập trình web và từng làm việc với nhiều framework, ngôn ngữ như PHP, JavaScript, React, jQuery, CSS, HTML, CakePHP, Laravel..., tôi hy vọng những kiến thức được chia sẻ tại đây sẽ hữu ích và thiết thực cho các bạn.
Xem thêm

Chào, tôi là Vũ. Đây là blog hướng dẫn lập trình của tôi.
Liên hệ công việc qua email dưới đây.
lhvuctu@gmail.com