Type something to search...
Cách dùng Gate Policy xử lý phân quyển trong Laravel

Cách dùng Gate Policy xử lý phân quyển trong Laravel

Sử dụng Gates

Gate được định nghĩa cho phép hoặc từ chối một hành động nào đó của user. Gate sử dụng dữ liệu với tham số thứ nhất là user, các vị trí khác lần lượt ở vị trí tiếp theo Gate sẽ không gắn với model nào cả, Gate chỉ sử dụng thông tin được cung cấp bởi những tham số, Gate thường sẽ được sử dụng ở tầng Controller, để định nghĩa hành động của user là có được phép hay không. Gate được viết ở App\Providers\AuthServiceProvider và sử dung Gate facade

Tạo Gate

Ta định nghĩa gate trong app/Providers/AuthServiceProvider.php

<?phpnamespace App\Providers;
 use Illuminate\Support\Facades\Gate;use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;use Illuminate\Http\Request;
 class AuthServiceProvider extends ServiceProvider{
  /**
   * The policy mappings for the application.
   *
   * @var array
   */
  protected $policies = [
    'App\Model' => 'App\Policies\ModelPolicy',
  ];

  /**
   * Register any authentication / authorization services.
   *
   * @return void
   */
  public function boot()
  {
    $this->registerPolicies();

    Gate::define('update-post', function ($user, $post) {
      return $user->id == $post->user_id;
    });
  }}

Gate được định nghĩa trả về True hoặc False dự theo điều kiện bạn viết trong gates.

Sử dụng trong controller

Tạo Postcontroller.php

<?phpnamespace App\Http\Controllers;
 use App\Http\Controllers\Controller;use App\Post;use Illuminate\Support\Facades\Gate;
 class PostController extends Controller{
  /* Make sure you don't user Gate and Policy altogether for the same Model/Resource */
  public function gate()
  {
    $post = Post::find(1);

    if (Gate::allows('update-post', $post)) {
      echo 'Allowed';
    } else {
      echo 'Not Allowed';
    }

    exit;
  }}

Sử dụng Gate::allows để kiểm tra xem user có quyền thực hiện hành động đó hay không

Sử dụng Policies

Policy nhận tham số đầu tiên là user đang đăng nhập Trong policy, Model User cung cấp hai phương thức hữu ích cho việc xác thực là can và cant. Phương thức can xác nhận việc user có thể thực hiện một hành động nào đó, còn cant xác nhận việc user không thể thực hiện hành động được chỉ định.

Policy thường được sử dụng với các hành động thao tác dữ liệu với các model như thêm sửa xóa dữ liệu.

Tạo Policies

Sử dụng câu lệnh Artisan make:policy để tạo policy cần thiết, các policy được tạo ra sẽ được đặt trong thư mục app\Policies.

php artisan make:policy PostPolicy

câu lệnh make:policy sẽ sinh ra một class policy rỗng, nếu bạn muốn sinh ra một CRUD policy bạn cần thêm tham số –model khi thực thi câu lệnh artisan:

php artisan make:policy PostPolicy —model=Post

Ta có thể viết PostPolicy như sau

<?phpnamespace App\Policies;
 use App\User;use App\Post;use Illuminate\Auth\Access\HandlesAuthorization;
 class PostPolicy{
  use HandlesAuthorization;

  public function view(User $user, Post $post)
  {
    return TRUE;
  }

  public function create(User $user)
  {
    return $user->id > 0;
  }

  public function update(User $user, Post $post)
  {
    return $user->id == $post->user_id;
  }

  public function delete(User $user, Post $post)
  {
    return $user->id == $post->user_id;
  }}

Đăng ký Policies

Ta phải đăng ký thì mới có thể sử dụng được policy, AuthServiceProvider được đưa vào trong project Laravel chứa một thuộc tính policies để map Eloquent model với các policy tương ứng. Đăng ký một policy để chỉ dẫn cho Laravel policy nào sẽ được sử dụng để phân quyền hành động cho model nào:

Ví dụ mình đăng ký 3 policy với 3 model

<?php
namespace App\Providers;
use App\Models\Office;use App\Models\Post;use App\Models\User ;use App\Policies\OfficePolicy;use App\Policies\PostPolicy;use App\Policies\UserPolicy;use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
         User::class => UserPolicy::class,
        Office::class => OfficePolicy::class,
        Post::class => PostPolicy::class,
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();
    }}

Sử dụng Policies trong controller

Ta kiểm tra trường hợp user có quyền tạo bài viết hay không

<?phpnamespace App\Http\Controllers;
use App\Http\Controllers\Controller;use App\Post;use Illuminate\Support\Facades\Auth;
class PostController extends Controller{
  public function create()
  {// User đang đăng nhập
    $user = Auth::user();

    if ($user->can('create', Post::class)) {
      echo 'Có quyền tạo bài viết.';
    } else {
      echo 'Không có quyền';
    }

    exit;
  }}

Ở đây ta sử dung hàm can để kiểm tra, ngoài ra còn các cách kiểm tra khác như

Ở controller sử dụng

$this->authorize(‘update’, $post);

Ở model

if ($user->can('update', $post)) {
  //}

Sử dụng ở Moddleware

use App\Post;
Route::put('/post/{post}', function (Post $post) {
   // The current user may update the post...})->middleware('can:update,post');

Sử dụng ở Blade Templates:

@can('update', $post)<!-- The Current User Can Update The Post -->
@elsecan('create', App\Post::class)
    <!-- The Current User Can Create New Post -->
@endcan

Hoặc sử dụng kết hợp middleware

<?php
namespace App\Policies;
use App\Models\User;use Illuminate\Auth\Access\HandlesAuthorization;
class PostPolicy{
    use HandlesAuthorization;

    public function create(User $user)
    {
        return $user->hasPermission('create_post');
    }}

Related Posts

Authencation với package Laravel Sanctum API

Authencation với package Laravel Sanctum API

Sanctum giải quyết 2 vấn đề: 1. API TokensSanctum sẽ sinh ra API tokens cho người dùng mà không cần đến sự phức tạp của Oauth. Nó giống như tính năng "access tokens" của GitHub. Hãy tưởng tư

read more
Sử dụng breadcrumbs với package Dialectic/Breadcrumb trong Laravel

Sử dụng breadcrumbs với package Dialectic/Breadcrumb trong Laravel

Trong suốt quá trình phát triển web, chúng ta thường tập trung thời gian cho những tính năng khó và lớn trước, sau đó là những phần "râu ria" như breadcrumb, favicon,... Breadcrumbs là một trong nhữn

read more
Sử dụng mô hình cây phân cấp category trong Laravel

Sử dụng mô hình cây phân cấp category trong Laravel

Nếu bạn đã từng xây dựng mô hình menu đa cấp hay gì đó đại loại như xây dựng danh sách cấu trúc lồng nhau thì chắc hẳn bạn đã từng dùng đệ quy để làm việc này nhưng đệ qui là phương pháp không được k

read more