# 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 %}