# 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 這樣不需要才不用讓權限去跑 ![](https://i.imgur.com/7CCrIsg.png) ## view 用boolean最好要加入問號 ![](https://i.imgur.com/9DdDAjJ.jpg) ## gate 去auth專屬的provider註冊 這才是全域 ### Gate::define ![](https://i.imgur.com/vNwp8LX.png) **註冊** 第一個是名字(能力的名字) 第二參數是閉包,有兩個參數 (第一個一定是user 第二個是要自已傳入,再引入時候,不需要用到時候可以不用傳入 沒有要對model的user做判斷時候 ) (閉包要return喔) **使用** ![](https://i.imgur.com/cg2e6Sz.png) 用 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。 ![](https://i.imgur.com/TT3YgoI.png) 可以取代 ``` if(Gate::denies('delete-post',$post)){ about(403,'no use') } ``` 變成 `$this->authorize('delete-post',$post);` 可以不用在about 更快 但這也要findOrFail 在傳入post ### forUser() ![](https://i.imgur.com/DnuqK9d.png) $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定義超級管理員 ![](https://i.imgur.com/9v1uYKs.png) 這邊是限定超級管理員只能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` 第一步 註冊 ![](https://i.imgur.com/eltndwV.png) 要在gate 那邊註冊 因為他本來就是gate 只是把它用一個資料夾叫policy來管理而已 這邊重點 要用. ex post.update這種去命名 不能跟之前一樣用post-update這樣 **下一步就是進階用resoucre** 這對應的是 **post.create** **post.view** **post.update** **post.delete** ![](https://i.imgur.com/9snfsqo.png) 你可以想成它是對應controller的 **這樣定義resource有一個缺點** 要知道她是對應哪個然後還有post 之類的前墜 多了就很難管理 所以 到最上面array那邊註冊model ![](https://i.imgur.com/Ng9KMrD.png) 因為下面有 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那邊 ![](https://i.imgur.com/d704Eit.png) ![](https://i.imgur.com/zjIV12A.png) ## 個人總結 註冊可以在 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 ![](https://i.imgur.com/DEj1qQ2.jpg) 驗證 ![](https://i.imgur.com/5HCPnyr.jpg) ###### tags: `Laravel`