昨天設定修改資料表以符合需求,接下來要設定權限部分,打算分兩種會員 管理員與一般會員。
權限 | 說明 |
---|---|
管理員 | 可以做所有的新增刪除修改 |
一般會員 | 可以新增動物而已,並且只能修改自己新增的動物。無法新增刪除修改分類 |
新建一個原則 policy
php artisan make:policy AnimalPolicy -m Animal
註冊policy
app/Providers/AuthServiceProvider.php
/**
* 應用程式的原則對應。
*
* @var array
*/
protected $policies = [
Animal::class => AnimalPolicy::class,
];
Controller 內檢查授權
在預計檢查授權的地方加入下方程式碼!
$this->authorize('update', $animal);
上面的程式碼是在檢查權限時使用,可以把它加在AnimalController 的 update 方法中,執行到這一行就會檢查權限。
因為剛剛已經把Animal 註冊到 AnimalPolicy 對應的物件,所以只要把 $animal 這個實體 放在第二個參數,第一個參數加入 AnimalPolicy 裡面的方法就可以囉!
檢查的原則要寫在AnimalPolicy 檔案裡,馬上撰寫檢查的原則。
撰寫原則
撰寫原則基本上只要專注於能不能做這一個操作的邏輯判斷就好,可以做回傳true 不能做 回傳 false。
例如誰可以更新動物資料的判斷邏輯,刊登的動物資料只能讓相同使用者更新,或是管理員可以編輯所有動物的資料。
打開 app/Policies/AnimalPolicy.php
剛剛新增的檔案,找到 update 方法,在方法中撰寫你想完成的邏輯程式。
public function update(User $user, Animal $animal)
{
// 只有刊登動物的會員可以操作更新的動作。
if ($user->id === $animal->user_id) {
return true;
}
return false;
}
如上所示 簡單的判斷 user 的 Id 要和 目前要編輯的動物資料中的 user_id 相同 才回傳 true 反之回傳 false。
原則的方法中如果回傳為true那麼表示檢查通過,在我們設定檢查的地方,將會運行這個方法,如果false,會返回 403 沒有權限的 回應給使用者。
攔截所有檢查
管理員可以操作全部的動物資料,可以用下面的方法撰寫,不需要在每一個 update、create、delete 的方法中都寫有關於管理員的判斷,只要在 AnimalPolicy 中定義一個 before 方法。這個方法會在其他檢查原則之前執行。
public function before($user, $ability)
{
// 昨天新建的
if ($user->permission== 'admin') {
return true;
}
}
這樣就可以略過所有管理員直接讓他可以操作動物這個資源。
AnimalPolicy 程式碼
<?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)
{
// 軟體刪除後,強制刪除資料表的動物資料。類似資料丟到垃圾桶後,要永久刪除資料的時判斷的邏輯。
// 因為沒有實作軟刪除的部分,這部分直接空著
}
}