會員權限設計(管理員、一般會員)

昨天設定修改資料表以符合需求,接下來要設定權限部分,打算分兩種會員 管理員與一般會員。

權限說明
管理員可以做所有的新增刪除修改
一般會員可以新增動物而已,並且只能修改自己新增的動物。無法新增刪除修改分類

新建一個原則 policy

php artisan make:policy AnimalPolicy -m Animal
產生policy檔案

註冊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)
    {
        // 軟體刪除後,強制刪除資料表的動物資料。類似資料丟到垃圾桶後,要永久刪除資料的時判斷的邏輯。
        // 因為沒有實作軟刪除的部分,這部分直接空著
    }
}

參考文件

https://laravel.com/docs/5.8/authorization


發佈留言