Kiểm soát quyền truy cập dữ liệu bằng Gate và Policy
Sau khi hoàn thành:
Bài 21 — Laravel Breeze
Bài 22 — Login
Bài 23 — Register
Bài 24 — Middleware
Chúng ta đã có hệ thống:
✅ Đăng ký tài khoản
✅ Đăng nhập
✅ Session Authentication
✅ Bảo vệ Route bằng Middleware
Nhưng hiện tại Laravel mới chỉ biết:
"Người này đã đăng nhập hay chưa?"
Ví dụ:
Route::middleware('auth')->group(function(){
Route::get('/dashboard', function(){
return view('dashboard');
});
});
Middleware auth chỉ kiểm tra:
User có đăng nhập?
|
|
Có
|
Cho phép truy cập
Nhưng trong thực tế CMS Blog cần nhiều hơn:
Ví dụ:
User A tạo bài viết:
ID: 10
Title: Laravel 12 Tutorial
User_id: 5
User B đăng nhập.
Nếu User B truy cập:
/posts/10/edit
thì sao?
Nếu chỉ dùng:
Route::middleware('auth')
Laravel sẽ cho phép.
Vấn đề:
User B
|
|
V
Sửa bài viết của User A
Đây là lỗi phân quyền.
1. Authentication và Authorization khác nhau
Hai khái niệm rất dễ nhầm.
Authentication
(Authentication = Xác thực)
Câu hỏi:
Bạn là ai?
Ví dụ:
Login:
Email:
admin@gmail.com
Password:
******
Laravel kiểm tra:
Database users
email
password
Kết quả:
OK
User ID = 1
Authorization
(Authorization = Phân quyền)
Câu hỏi:
Bạn được phép làm gì?
Ví dụ:
User:
id: 5
name: Nam
role: user
Admin:
id: 1
name: Admin
role: admin
Quyền:
| Chức năng | Admin | User |
|---|---|---|
| Xem bài viết | ✅ | ✅ |
| Tạo bài viết | ✅ | ✅ |
| Sửa bài người khác | ✅ | ❌ |
| Xóa user | ✅ | ❌ |
| Quản lý hệ thống | ✅ | ❌ |
2. Authorization trong Laravel
Laravel cung cấp 3 cơ chế chính:
Authorization
|
|
---------------------
| |
Gate Policy
| |
Logic nhỏ Logic theo Model
3. Gate là gì?
Gate dùng cho các quyền đơn giản.
Ví dụ:
Chỉ Admin được vào trang quản trị.
Tạo Gate
Mở:
app/Providers/AppServiceProvider.php
Thêm:
use Illuminate\Support\Facades\Gate;
use App\Models\User;
public function boot(): void
{
Gate::define('admin', function(User $user){
return $user->role === 'admin';
});
}
Ý nghĩa:
Khi gọi:
Gate::allows('admin')
Laravel chạy:
$user->role === 'admin'
Nếu:
admin
trả về:
true
4. Sử dụng Gate trong Controller
Ví dụ:
AdminController:
use Illuminate\Support\Facades\Gate;
public function index()
{
if(!Gate::allows('admin')){
abort(403);
}
return view('admin.index');
}
Nếu User thường truy cập:
/admin
Laravel trả:
403 Forbidden
5. Middleware Authorization
Laravel có sẵn middleware:
can
Ví dụ:
Route::get('/admin',
[
AdminController::class,
'index'
])
->middleware('can:admin');
Bây giờ:
Admin
|
OK
User
|
403
6. Policy là gì?
Gate phù hợp với quyền đơn giản.
Nhưng Blog CMS có nhiều quyền:
Ví dụ Post:
Post
create
read
update
delete
restore
forceDelete
Không nên viết:
if($user->role=='admin')
ở khắp Controller.
Code sẽ rất rối.
Giải pháp:
Policy
Policy gom toàn bộ quyền của một Model.
Ví dụ:
PostPolicy.php
7. Tạo Policy
Chạy:
php artisan make:policy PostPolicy --model=Post
Laravel tạo:
app
|
Policies
|
PostPolicy.php
Nội dung:
class PostPolicy
{
}
Laravel tạo sẵn:
viewAny()
view()
create()
update()
delete()
restore()
forceDelete()
8. Viết quyền Update Post
Ví dụ:
User chỉ sửa bài của mình.
Post:
id
title
content
user_id
User:
id = 5
Post:
user_id = 5
Cho phép.
Code:
public function update(
User $user,
Post $post
){
return $user->id === $post->user_id;
}
Logic:
User đăng nhập
|
|
Post owner?
|
--------------
| |
Yes No
Cho sửa 403
9. Đăng ký Policy
Laravel 12 tự động phát hiện theo convention:
Model:
App\Models\Post
Policy:
App\Policies\PostPolicy
Laravel tự map:
Post
+
PostPolicy
Không cần khai báo.
10. Dùng Policy trong Controller
Ví dụ:
PostController:
public function edit(Post $post)
{
$this->authorize(
'update',
$post
);
return view(
'posts.edit',
compact('post')
);
}
Nếu:
User_id = Post.user_id
cho phép.
Ngược lại:
403 Forbidden
11. Route Authorization
Có thể viết trực tiếp:
Route::get(
'/posts/{post}/edit',
[
PostController::class,
'edit'
]
)
->middleware(
'can:update,post'
);
Laravel hiểu:
can:
update
Model:
post
12. Blade kiểm tra quyền
Trong giao diện:
Ví dụ nút Edit:
@can('update',$post)
<a href="#">
Edit
</a>
@endcan
Nếu User không có quyền:
Nút không xuất hiện.
13. Thêm cột role cho User
Migration:
php artisan make:migration add_role_to_users_table
Migration:
Schema::table('users', function(Blueprint $table){
$table->string('role')
->default('user');
});
Chạy:
php artisan migrate
Database:
users
| id | name | role |
|---|---|---|
| 1 | Admin | admin |
| 2 | Nam | user |
| 3 | Lan | user |
14. Tạo helper isAdmin()
Trong Model User:
public function isAdmin()
{
return $this->role === 'admin';
}
Sử dụng:
if(auth()->user()->isAdmin()){
echo "Admin";
}
15. Ví dụ Blog CMS hoàn chỉnh
Admin
Dashboard
|
|
CRUD Categories
|
|
CRUD Users
|
|
Delete Post
User
Dashboard
|
|
Create Post
|
|
Edit Post của mình
|
|
Delete Post của mình
16. Luồng phân quyền chuẩn Laravel CMS
User Login
|
|
Authentication
|
|
Middleware auth
|
|
Authorization
|
|
Gate / Policy
|
|
Allow / Deny
17. Cấu trúc dự án sau bài 25
app
├── Models
│ ├── User.php
│ └── Post.php
├── Policies
│ └── PostPolicy.php
├── Http
│ ├── Controllers
│ │
│ └── Middleware
routes
└── web.php
18. Kiến thức đạt được sau bài này
Sau bài 25, người học hiểu:
✅ Authentication khác Authorization
✅ Gate trong Laravel
✅ Policy trong Laravel
✅ $this->authorize()
✅ can Middleware
✅ Blade @can
✅ Phân quyền Admin/User
✅ Bảo vệ dữ liệu theo User sở hữu
Chuẩn bị cho Bài 26
📘 Bài 26 — Roles & Permissions
Chúng ta sẽ nâng cấp từ:
role = admin/user
thành hệ thống thực tế:
Users
|
Roles
|
Permissions
Admin
├── create_post
├── edit_post
├── delete_user
Editor
├── edit_post
User
├── create_post
Kết hợp:
Middleware Admin
Permission table
Role table
Pivot relationship
Phân quyền CRUD hoàn chỉnh cho Blog CMS Laravel 12.



Không có nhận xét nào:
Đăng nhận xét