# laravel Gate authoize policy
歐洲laravel
https://www.youtube.com/watch?v=B2M3FCjRz6w
記得要定義關係喔
因為gate註冊crud太亂了才有policy
但不是他比較好
命名 post.update
因為會對應controller所以才用 .
這是它命名規則
**authoize的預設規則**
https://www.bilibili.com/video/BV1Ue411p7te/?spm_id_from=333.788.recommend_more_video.17
必看(https://laracasts.com/series/laravel-from-scratch-2018/episodes/27)
## blade使用時
@can外面包一個auth
這樣不需要才不用讓權限去跑

## view 用boolean最好要加入問號

## gate
去auth專屬的provider註冊
這才是全域
### Gate::define

**註冊**
第一個是名字(能力的名字)
第二參數是閉包,有兩個參數
(第一個一定是user 第二個是要自已傳入,再引入時候,不需要用到時候可以不用傳入 沒有要對model的user做判斷時候 )
(閉包要return喔)
**使用**

用 Gate::denies
第一個參數是user(驗證過的)
第二參數是要傳入的
記住
這要自己用about
他不會自動幫你回傳錯誤status
只是你看截圖
你這樣要findOrfaill
但可以又model綁定方法
這種
Gate::allow('update-post',$post)
這邊的$post經過model了
### authorize helper(controller驗證)
基底的 App\Http\Controllers\Controller 類別包含了 Laravel 使用的 AuthorizesRequests trait。此 trait 提供了 authorize 方法,它可以被用於快速授權一個給定的行為,當無權限執行該行為時會拋出 HttpException。

可以取代
```
if(Gate::denies('delete-post',$post)){
about(403,'no use')
}
```
變成
`$this->authorize('delete-post',$post);`
可以不用在about 更快
但這也要findOrFail
在傳入post
### forUser()

$user = User::find(1);
Gate::forUser($user)->denise('update-post',$post)
=> true
**這個使用者可以使用當前的post,他有權限**
Gate::forUser($user)->allows('update-post',$post)
=> false
**這個使用者可以使用所有的post,他有權限**
### before after
before在所有define之前
after在所有gate之後
一般都適用before定義超級管理員

這邊是限定超級管理員只能update-post
但可以拔掉就全部都能了
閉包 就return ture就好了
## policy
https://mark-lin.com/posts/20181214/
https://ithelp.ithome.com.tw/articles/10223360
**因為gate這樣一個一個定義太麻煩 也不好閱讀
所以產生policy**
針對一個 Model 或者資源限制權限的時候,可以使用的機制。
`php artisan make:policy PostPolicy --model=Post`
第一步 註冊

要在gate 那邊註冊 因為他本來就是gate 只是把它用一個資料夾叫policy來管理而已
這邊重點
要用. ex post.update這種去命名 不能跟之前一樣用post-update這樣
**下一步就是進階用resoucre**
這對應的是
**post.create**
**post.view**
**post.update**
**post.delete**

你可以想成它是對應controller的
**這樣定義resource有一個缺點**
要知道她是對應哪個然後還有post 之類的前墜
多了就很難管理
所以
到最上面array那邊註冊model

因為下面有
this->regiserPolicies
所以他會去找model
這樣
只要你controller傳進來的
是經過model find 找到的那個
就會自動對應
controller部分
可以$this->authorize('update',$post)這樣去對應
但也可以
$this->authorize($post)
這會自動對照你controller名稱
規則看下面
**這邊很特別store 跟 create是對照 create**
[
'show' => 'view'
'create' => 'create'
'store' => 'create'
'edit' => 'update'
'update' => 'update'
'destory' => 'delete'
]
**看不懂請看程式碼**
```
<?php
namespace App\Policies;
use App\User;
use App\Animal;
use Illuminate\Auth\Access\HandlesAuthorization;
class AnimalPolicy
{
use HandlesAuthorization;
public function before($user, $ability)
{
if ($user->isSuperAdmin()) {
return true;
}
}
/**
* Determine whether the user can view any animals.
*
* @param \App\User $user
* @return mixed
*/
public function viewAny(User $user)
{
//未登入也可以看所有動物資料,不需要用到這個方法
}
/**
* Determine whether the user can view the animal.
*
* @param \App\User $user
* @param \App\Animal $animal
* @return mixed
*/
public function view(User $user, Animal $animal)
{
//未登入也可以看動物資料,不需要用到這個方法
}
/**
* Determine whether the user can create animals.
*
* @param \App\User $user
* @return mixed
*/
public function create(User $user)
{
// 登入後認證授權確認皆可以創建送養動物資料,所以不需要製作這方法
// 是否有權限操作,請參考前幾天 Victor 的鐵人賽文章。
}
/**
* Determine whether the user can update the animal.
*
* @param \App\User $user
* @param \App\Animal $animal
* @return mixed
*/
public function update(User $user, Animal $animal)
{
// 修改動物資料必須檢查,動物是否是由該會員新建的,利用animal 的user_id 判斷
if ($user->id === $animal->user_id) {
return true;
}
return false;
}
/**
* Determine whether the user can delete the animal.
*
* @param \App\User $user
* @param \App\Animal $animal
* @return mixed
*/
public function delete(User $user, Animal $animal)
{
// 刪除動物資料必須檢查,動物是否是由該會員新建的,利用animal 的user_id 判斷
if ($user->id === $animal->user_id) {
return true;
}
return false;
}
/**
* Determine whether the user can restore the animal.
*
* @param \App\User $user
* @param \App\Animal $animal
* @return mixed
*/
public function restore(User $user, Animal $animal)
{
// 軟體刪除後「復原用」類似丟到資料丟到垃圾桶後,要再把資料救回來時判斷。
// 因為沒有實作軟刪除的部分,這部分直接空著
}
/**
* Determine whether the user can permanently delete the animal.
*
* @param \App\User $user
* @param \App\Animal $animal
* @return mixed
*/
public function forceDelete(User $user, Animal $animal)
{
// 軟體刪除後,強制刪除資料表的動物資料。類似資料丟到垃圾桶後,要永久刪除資料的時判斷的邏輯。
// 因為沒有實作軟刪除的部分,這部分直接空著
}
}
```
## blade 方面
因為policy跟gate都是controller再用
但這樣你blade還是看得到按鈕
@can('update', $post)
一樣第一個是policy或gate的名稱
第二個是model find的那個 一樣要實例
## 使用時機
policy在使用resoucre 跟 model的情況下是最好
對於特定資源跟model的權限許可
gate比較是全域的 跟model比較沒關係的定義用gate
但公司很厲害使用
gate放在model裡面
## middware
用can middware 這本來就註冊了
:後面一樣是船參數 所以這會去叫home.secrect的gate那邊


## 個人總結
註冊可以在
prodioder那邊註冊
用gate
太亂所以有另外開的較policy對應crud
使用上
controller呼叫
authorize
gate
auth->user()->can()
或在blade使用
@can()
或在route用middware('can:update,product')
對應的是
Route::resorce('/product',prodcutController);
can後面接對應的註冊名稱
第二個是參數
因為是resorce所以會自動傳入
基本上使用可以一個參數 往上看
不然就兩個參數通用
別特別記了
基本上都用polcy
全域像是超級管理員那種才會去povider註冊
## permission來源
第一階段思考要放進database

驗證

###### tags: `Laravel`