# Laravel - Authorization ## 簡介 什麼是 authorization ? 就是當使用者想要做某件事情時, 他是否具有權限去做這個動作, 像是工作上可能有職位高低的不同 A 具有存取後台營收頁面的權利但 B 不具有, 像是情況larael有提供方便的機制去做處理分別是 `gate` 和 `policy` - gate:比較客製化的 - policy:和特定的 model 或 resource 有關 ## Gates ### 建立/註冊 ```php= // App\Providers\AuthServiceProvider // 第一種寫法 public function boot() { $this->registerPolicies(); Gate::define('update-post', function (User $user, Post $post) { return $user->id === $post->user_id; }); } // 第二種 public function boot() { $this->registerPolicies(); Gate::define('update-post', [PostPolicy::class, 'update']); } ``` ### 授權動作 要授權動作有兩個 methods 分別是 `allows` 和 `denies ` ```php= // PostController public function update(Request $request, Post $post) { if (! Gate::allows('update-post', $post)) { abort(403); } // Update the post... } ``` 要注意的是laravel會自動幫你把 auth user 丟進去但如果想要丟別的使用者進去可以用 ```php= if (Gate::forUser($user)->allows('update-post', $post)) { // The user can update the post... } ``` 授權多個動作 ```php= if (Gate::any(['update-post', 'delete-post'], $post)) { // The user can update or delete the post... } if (Gate::none(['update-post', 'delete-post'], $post)) { // The user can't update or delete the post... } ``` ### 額外動作 相關 methods `allows` `denies` `check` `any` `none` `authorize` `can` `cannot` 需要帶更多變數 ```php= Gate::define('create-post', function (User $user, Category $category, $pinned) { ... } if (Gate::check('create-post', [$category, $pinned])) { // The user can create the post... } ``` ### 回傳 如果不具權限自動丟出 AuthorizationException 錯誤 ```php= Gate::authorize('edit-settings'); // The action is authorized... ``` ## Policies policy 授權的邏輯是圍繞在 model 或 resource, 假設你的網站是一個blog那麼應該會有 App\Models\Post 那相對應的就會有 App\Policies\PostPolicy 去授權更新刪除之類的 ### 建立 ``` // 會建立空的 php artisan make:policy PostPolicy // 與 model 有關 php artisan make:policy PostPolicy --model=Post ``` ### 註冊 - 手動註冊 ```php= // App\Providers\AuthServiceProvide protected $policies = [ Post::class => PostPolicy::class, ]; ``` - 自動註冊 如果有遵守 laravel 的 naming convention 那麼 laravel 會去檢查 `app/Models` 並且自動去註冊 `app/Policies` 裡的 policy ## 寫 ```php= class PostPolicy { public function update(User $user, Post $post) { return $user->id === $post->user_id; } } ``` ## 條件式觸發 ```php= // class PostPolicy public function before(User $user, $ability) { if ($user->isAdministrator()) { return true; } } ``` ## 呼叫方式 ### [Via The User Model](https://laravel.com/docs/8.x/authorization#via-the-user-model) ### [Actions That Don't Require Models](https://laravel.com/docs/8.x/authorization#controller-actions-that-dont-require-models) - [Via Controller Helpers](https://laravel.com/docs/8.x/authorization#via-controller-helpers) - [Authorizing Resource Controllers](https://laravel.com/docs/8.x/authorization#authorizing-resource-controllers) ### [Via Middleware](https://laravel.com/docs/8.x/authorization#via-middleware) ### [Actions That Don't Require Models](https://laravel.com/docs/8.x/authorization#middleware-actions-that-dont-require-models) ###### tags: `2021` `草稿` `laravel` {%hackmd BJrTq20hE %}