Tính nhất quán cực kỳ quan trọng trong việc lập trình cơ bản, cho dù bạn là một người chơi hệ solo hay một người code trong team. Việc thiết lập/quy định một số nguyên tắc cơ bản của một số loại logic nhất định trong cách code của bạn, nó sẽ giúp cho ứng dụng/dự án của bạn dễ dàng code hơn.
Lấy ví dụ, bạn nên triển khai logic của việc xác minh ở đâu? Bạn nên thực thi những kiểm tra phân quyền này như thế nào? Bạn có thể thực hiện việc kiểm tra trong một biểu mẫu (form), bên trong một Controller, bên trong middleware, hoặc thậm chí trong view.
form
Controller
middleware
view
Hãy bắt đầu với vị trí đặt kiểm tra phân quyền, chúng ta nên sử dụng các policies của Laravel ngay khi nào có thể. Policies provider cung cấp một vị trí trung tâm để lưu giữ tất cả những logic phân quyền cho một route resource cụ thể. Các quy ước này tồn tại song song với những hành động (action controller) điển hình mà bạn muốn thực hiện trên Controller được ánh xạ trực tiếp vào các quy ước trong Controller (nói văn này hơi khó hiểu, nhưng hiểu đơn giản là các logic trong Policies của Laravel có liên quan trực tiếp đến Controller và router resouce)
policies
Policies provider
route resource
action controller
Ví dụ:
policies update()
function update()
route::resource()
policies viewAny()
function index()
Nếu bạn chưa sử dụng các function mặc định trong Controller resource (bao gồm index(), create(), store(), show(), edit(), update(), destroy()), bạn vẫn có thể thêm những hàm tùy chọn của bạn vào policies khi cần. Ngoài ra, nếu bạn sử dụng Laravel Nova vào trong dự án của mình, nó sẽ tận dụng các policies mà bạn đã xây dựng cho dự án của bạn.
index(), create(), store(), show(), edit(), update(), destroy()
Nếu bạn đang sử dụng các function mặc định trong Controller resource, bạn có thể lập phân quyền cho toàn bộ Controller thông qua một dòng code:
public function __construct() { $this->authorizeResource(Post::class, 'post'); }
Nếu bạn không sử dụng các function mặc định trong Controller resource, bạn có thể đặt kiểm tra bên trong Controller với một dòng như sau:
$this->authorize('post', Post::class);
Một trong những lợi ích của việc sử dụng phân quyền này là việc nó trả về mã trạng thái HTTP (403) khi bạn không có quyền hạn nhất định.
Mẹo chính của bài viết này chính là việc bạn kiểm tra phân quyền càng sớm càng tốt trong một request yêu cầu, việc bạn kiểm tra phân quyền càng trễ thì website phải xử lý càng nhiều tác vụ trước khi có thể kiểm tra, việc này sẽ làm tiêu tốn tài nguyên và hiệu năng của website.
Route::middleware('can:manage-posts')->group(function () { Route::get('posts/{post}/approve-post', ApprovePostController::class); Route::resource('posts', PostsController::class); });
Tuy nhiên trong một số trường hợp phân quyền, bạn phải kiểm tra phân quyền ở nhiều nơi, điều này cũng hợp lý thôi, vì tùy vào ngữ cảnh mà bạn sử dụng policies theo cách của riêng mình, dưới đây là ví dụ cập nhật thông tin users cho một request API của Admin.
// Trong Router Route::resource('users', 'UserController')->middleware(['auth:sanctum']); // ở đây mình sử dụng Laravel Sanctum để xác minh token của API /** Trong Controller cụ thể là function update() */ // Nếu admin có quyền chỉnh sửa địa chỉ email của người dùng if (auth()->user()->can('email', $model)) { $model->email = request('email'); } // Nếu admin có quyền chỉnh sửa username của người dùng if (auth()->user()->can('username', $model)) { $model->username = request('username',null); }
Đến đây thì mẹo thứ bảy đã kết thúc, rất cảm ơn bạn đã chịu khó đọc đến đây, nếu có chỗ nào khó hiểu, bạn có thể để lại bình luận, mình sẽ trả lời lại cho các bạn trong sự hiểu biết của mình nhé. Hẹn gặp lại bạn trong mẹo tiếp theo.