1. Code
  2. PHP
  3. Laravel

Gates dan Policies di Laravel

Hari ini, kita akan membahas sistem authorization Laravel web framework. Laravel framework mengimplementasikan authorization dalam bentuk gates dan policies. Setelah pengenalan gates dan policies, saya akan menunjukkan konsep-konsep dengan menerapkan sebuah contoh custom.
Scroll to top

Indonesian (Bahasa Indonesia) translation by Sap (you can also view the original English article)

Hari ini, kita akan membahas sistem authorization Laravel web framework. Laravel framework mengimplementasikan authorization dalam bentuk gates dan policies. Setelah pengenalan gates dan policies, saya akan menunjukkan konsep-konsep dengan menerapkan sebuah contoh custom.

Saya berasumsi bahwa Anda sudah menyadari built-in sistem authentication Laravel karena itu adalah sesuatu yang penting untuk memahami konsep authorization. Jelas, sistem authorization yang bekerja dalam hubungannya dengan sistem authentication untuk mengidentifikasi sesi pengguna yang sah.

Jika Anda tidak menyadari sistem Laravel authentication, saya akan sangat menyarankan pergi ke dokumentasi resmi, yang menyediakan Anda dengan wawasan hands-on terhadap subjek.

Laravel's pendekatan untuk Authorization

Sekarang, Anda harus tahu bahwa sistem Laravel authorization datang dalam dua rasa — gates dan policies. Walaupun mungkin terdengar seperti urusan yang rumit, saya akan mengatakan ini sangat mudah untuk mengimplementasikan hal ini sekali Anda dapat menguasainya!

Gates memungkinkan Anda untuk menentukan aturan authorization yang menggunakan pendekatan berbasis closure. Dengan kata lain, ketika Anda ingin memberikan authorize tindakan yang tidak berhubungan dengan model tertentu, gate adalah tempat yang sempurna untuk menerapkan logika.

Mari kita lihat sekilas authorization berbasis-gate yang tampak seperti:

1
...
2
...
3
Gate::define('update-post', function ($user, $post) {
4
  return $user->id == $post->user_id;
5
});
6
...
7
...

Potongan di atas mendefinisikan aturan authorization update-post yang Anda bisa call dari manapun dalam aplikasi Anda.

Di sisi lain, Anda harus menggunakan policies bila Anda ingin group logika authorization setiap model. Sebagai contoh, katakanlah Anda memiliki model Post dalam aplikasi Anda, dan Anda ingin authorize model actions CRUD. Dalam hal ini, itu adalah policy yang Anda butuhkan untuk menerapkannya.

1
class PostPolicy
2
{
3
  public function view(User $user, Post $post) {}
4
  public function create(User $user) {}
5
  public function update(User $user, Post $post) {}
6
  public function delete(User $user, Post $post) {}
7
}

Seperti yang Anda lihat, itu adalah policy class sederhana yang mendefinisikan authorization untuk tindakan CRUD model Post.

Jadi itu sebuah pengenalan gates dan policies di Laravel. Dari bagian berikutnya dan seterusnya, kita akan mulai melalui demonstrasi praktek dari setiap elemen.

Gates

Dalam bagian ini, kita akan melihat sebuah contoh nyata untuk memahami konsep gates.

Lebih sering daripada tidak, Anda akan melihat Laravel service provider ketika Anda harus mendaftar component atau service. Mengikuti konvensi itu, mari kita lanjutkan ke depan dan menentukan kustom gate dalam app/Providers/AuthServiceProvider.php seperti yang ditunjukkan dalam potongan berikut.

1
<?php
2
namespace App\Providers;
3
4
use Illuminate\Support\Facades\Gate;
5
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
6
use Illuminate\Http\Request;
7
8
class AuthServiceProvider extends ServiceProvider
9
{
10
  /**

11
   * The policy mappings for the application.

12
   *

13
   * @var array

14
   */
15
  protected $policies = [
16
    'App\Model' => 'App\Policies\ModelPolicy',
17
  ];
18
19
  /**

20
   * Register any authentication / authorization services.

21
   *

22
   * @return void

23
   */
24
  public function boot()
25
  {
26
    $this->registerPolicies();
27
    
28
    Gate::define('update-post', function ($user, $post) {
29
      return $user->id == $post->user_id;
30
    });
31
  }
32
}

Dalam method boot, kita sudah didefinisikan custom gate:

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

Sementara mendefinisikan gate, dibutuhkan closure yang mengembalikan TRUE atau FALSE berdasarkan logika authorization yang didefinisikan dalam definisi gate. Selain function closure, ada cara lain Anda dapat menetapkan gates.

Sebagai contoh, definisi gate berikut memanggil action controller bukan function closure.

1
Gate::define('update-post', 'ControllerName@MethodName');

Sekarang, mari kita lanjutkan dan menambahkan kostum route sehingga kita bisa melanjutkan melalui demonstrasi bagaimana gate-based authorization bekerja. Dalam route file routes/web.php, mari kita menambahkan route berikut.

1
Route::get('service/post/gate', 'PostController@gate');

Mari kita membuat controller terkait file app/Http/Controllers/PostController.php juga.

1
<?php
2
namespace App\Http\Controllers;
3
4
use App\Http\Controllers\Controller;
5
use App\Post;
6
use Illuminate\Support\Facades\Gate;
7
8
class PostController extends Controller
9
{
10
  /* Make sure you don't user Gate and Policy altogether for the same Model/Resource */
11
  public function gate()
12
  {
13
    $post = Post::find(1);
14
15
    if (Gate::allows('update-post', $post)) {
16
      echo 'Allowed';
17
    } else {
18
      echo 'Not Allowed';
19
    }
20
    
21
    exit;
22
  }
23
}

Dalam kebanyakan kasus, Anda akan berakhir menggunakan baik allows atau denies method Gate facade untuk authorize tindakan tertentu. Dalam contoh kita di atas, kami telah menggunakan method allows untuk memeriksa apakah pengguna saat ini dapat melakukan tindakan update-post.

Pengguna dengan mata tajam akan menyadari bahwa kami hanya melewati argumen kedua $post untuk closure. Argumen pertama, pengguna saat ini masuk, secara otomatis injected oleh Gate facade.

Jadi itulah bagaimana Anda seharusnya menggunakan gates untuk authorize tindakan dalam aplikasi Laravel. Bagian berikutnya semua tentang bagaimana menggunakan policies, jika Anda ingin menerapkan authorization untuk model Anda.

Policies

Seperti yang kita bahas sebelumnya, bila Anda ingin logika tindakan group authorization Anda untuk model tertentu atau resource, itu adalah policy yang Anda cari.

Dalam bagian ini, kita akan membuat kebijakan untuk model Post yang akan digunakan untuk authorize semua tindakan CRUD. Saya berasumsi bahwa Anda sudah siap menerapkan model Post dalam aplikasi Anda; Jika tidak, sesuatu yang serupa akan dilakukan.

Perintah artisan Laravel adalah teman terbaik Anda ketika datang untuk menciptakan kode mematikan. Anda dapat menggunakan perintah artisan berikut untuk membuat policy untuk Post model.

1
$php artisan make:policy PostPolicy --model=Post

Seperti yang Anda lihat, kami telah disediakan argumen --model =Post sehingga menciptakan semua method-method CRUD. Dalam ketiadaan itu, itu akan membuat class Policy yang kosong. Anda dapat menemukan Policy class baru dibuat di app/Policies/PostPolicy.php.

Mari kita ganti dengan kode berikut.

1
<?php
2
namespace App\Policies;
3
4
use App\User;
5
use App\Post;
6
use Illuminate\Auth\Access\HandlesAuthorization;
7
8
class PostPolicy
9
{
10
  use HandlesAuthorization;
11
12
  /**

13
   * Determine whether the user can view the post.

14
   *

15
   * @param  \App\User  $user

16
   * @param  \App\Post  $post

17
   * @return mixed

18
   */
19
  public function view(User $user, Post $post)
20
  {
21
    return TRUE;
22
  }
23
24
  /**

25
   * Determine whether the user can create posts.

26
   *

27
   * @param  \App\User  $user

28
   * @return mixed

29
   */
30
  public function create(User $user)
31
  {
32
    return $user->id > 0;
33
  }
34
35
  /**

36
   * Determine whether the user can update the post.

37
   *

38
   * @param  \App\User  $user

39
   * @param  \App\Post  $post

40
   * @return mixed

41
   */
42
  public function update(User $user, Post $post)
43
  {
44
    return $user->id == $post->user_id;
45
  }
46
47
  /**

48
   * Determine whether the user can delete the post.

49
   *

50
   * @param  \App\User  $user

51
   * @param  \App\Post  $post

52
   * @return mixed

53
   */
54
  public function delete(User $user, Post $post)
55
  {
56
    return $user->id == $post->user_id;
57
  }
58
}

Untuk dapat menggunakan Policy class, kita perlu mendaftar menggunakan Laravel service provider seperti yang ditunjukkan dalam potongan berikut.

1
<?php
2
namespace App\Providers;
3
4
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
5
use Illuminate\Http\Request;
6
use App\Post;
7
use App\Policies\PostPolicy;
8
9
class AuthServiceProvider extends ServiceProvider
10
{
11
  /**

12
   * The policy mappings for the application.

13
   *

14
   * @var array

15
   */
16
  protected $policies = [
17
    'App\Model' => 'App\Policies\ModelPolicy',
18
    Post::class => PostPolicy::class
19
  ];
20
21
  /**

22
   * Register any authentication / authorization services.

23
   *

24
   * @return void

25
   */
26
  public function boot()
27
  {
28
    $this->registerPolicies();
29
  }
30
}

Kami telah menambahkan pemetaan Policy kami di properti $policies. Ia memberitahu Laravel untuk memanggil method policy tersebut untuk authorize tindakan CRUD.

Anda juga perlu mendaftarkan policies menggunakan method registerPolicies, seperti yang kami lakukan dalam method boot.

Bergerak lebih lanjut, mari kita membuat beberapa kustom route dalam file routes/web.php sehingga kita dapat menguji method Policy kami di sana.

1
Route::get('service/post/view', 'PostController@view');
2
Route::get('service/post/create', 'PostController@create');
3
Route::get('service/post/update', 'PostController@update');
4
Route::get('service/post/delete', 'PostController@delete');

Akhirnya, mari kita membuat controller terkait di app/Http/Controllers/PostController.php.

1
<?php
2
namespace App\Http\Controllers;
3
4
use App\Http\Controllers\Controller;
5
use App\Post;
6
use Illuminate\Support\Facades\Auth;
7
8
class PostController extends Controller
9
{
10
  public function view()
11
  {
12
    // get current logged in user

13
    $user = Auth::user();
14
    
15
    // load post

16
    $post = Post::find(1);
17
    
18
    if ($user->can('view', $post)) {
19
      echo "Current logged in user is allowed to update the Post: {$post->id}";
20
    } else {
21
      echo 'Not Authorized.';
22
    }
23
  }
24
25
  public function create()
26
  {
27
    // get current logged in user

28
    $user = Auth::user();
29
30
    if ($user->can('create', Post::class)) {
31
      echo 'Current logged in user is allowed to create new posts.';
32
    } else {
33
      echo 'Not Authorized';
34
    }
35
36
    exit;
37
  }
38
39
  public function update()
40
  {
41
    // get current logged in user

42
    $user = Auth::user();
43
44
    // load post

45
    $post = Post::find(1);
46
47
    if ($user->can('update', $post)) {
48
      echo "Current logged in user is allowed to update the Post: {$post->id}";
49
    } else {
50
      echo 'Not Authorized.';
51
    }
52
  }
53
54
  public function delete()
55
  {
56
    // get current logged in user

57
    $user = Auth::user();
58
    
59
    // load post

60
    $post = Post::find(1);
61
    
62
    if ($user->can('delete', $post)) {
63
      echo "Current logged in user is allowed to delete the Post: {$post->id}";
64
    } else {
65
      echo 'Not Authorized.';
66
    }
67
  }
68
}

Ada berbagai cara Anda dapat tindakan authorize Anda menggunakan Policies. Dalam contoh kita di atas, kami telah menggunakan model User untuk authorize tindakan model Post.

Model User menyediakan dua method yang berguna untuk tujuan authorization — can dan cant. Method can digunakan untuk memeriksa apakah user saat ini mampu melaksanakan tindakan tertentu. Dan pasangan dari method can, method cant, digunakan untuk menentukan ketidakmampuan pelaksanaan action.

Mari kita ambil code method view dari controller untuk melihat memang demikian

1
public function view()
2
{
3
  // get current logged in user

4
  $user = Auth::user();
5
  
6
  // load post

7
  $post = Post::find(1);
8
  
9
  if ($user->can('view', $post)) {
10
    echo "Current logged in user is allowed to update the Post: {$post->id}";
11
  } else {
12
    echo 'Not Authorized.';
13
  }
14
}

Pertama, kita memuat pengguna yang saat ini masuk, yang memberikan kita objek model User. Selanjutnya, kami memuat contoh post yang menggunakan model Post.

Bergerak maju, kami telah menggunakan method can dari model User untuk authorize tindakan view model Post. Argumen pertama method can adalah nama tindakan yang ingin Anda authorize, dan argumen kedua adalah objek model yang Anda ingin mendapatkan authorized.

Itu adalah sebuah demonstrasi tentang bagaimana menggunakan model User untuk authorize tindakan menggunakan policies. Atau, Anda bisa menggunakan Controller Helper juga, jika Anda berada dalam controller action authorizing tertentu.

1

2
$this->authorize('view', $post);
3

Seperti yang Anda lihat, Anda tidak perlu untuk memuat model User jika Anda menggunakan Controller Helper.

Jadi itu adalah konsep policies yang Anda inginkan, dan itu benar-benar berguna sementara authorizing model atau resource karena memungkinkan Anda untuk mengelompokkan logika authorization di satu tempat.

Hanya pastikan bahwa Anda tidak menggunakan gates dan policies seluruhnya untuk actions yang sama dari Model, sebaliknya hal itu akan membuat masalah. Itu dia dari saya untuk hari ini, dan saya sudahi hari ini!

Kesimpulan

Hari ini, Laravel authorization yang mengambil panggung di artikel saya. Di awal artikel, saya memperkenalkan unsur utama dari Laravel authorization, gates dan policies.

Setelah itu, kami melewati penciptaan kustom gate dan policy untuk melihat cara kerjanya di dunia nyata. Saya harap Anda telah menikmati artikel dan belajar sesuatu yang berguna dalam konteks Laravel.

Bagi Anda yang hanya akan mulai dengan Laravel atau mencari untuk memperluas pengetahuan Anda, situs, atau aplikasi dengan ekstensi, kami memiliki berbagai hal yang Anda dapat belajar di Envato Market.

Seperti biasa, saya akan senang mendengar dari Anda dalam bentuk komentar menggunakan feed di bawah ini!