iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 20
2
Modern Web

使用 Laravel 打造 RESTful API系列 第 20

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

使用Laravel 8 PHP主流框架打造RESTful API(iT邦幫忙鐵人賽系列書)ISBN:9789864345304

本系列文章已集結成冊與鐵人賽文章差異內容,有以下幾點:

更新至Laravel 8、基礎的PHP重點筆記、加強製作API流程細節、加入程式設計模式,優化、重構程式碼的部分,並且於書籍前面的章節介紹Git。

讓您從製作第一個簡單的API到優化自己的程式碼,分享我的經驗給您,打造自己的最強大腦API,若有興趣的朋友可以參考看看

天瓏網路書局:
https://www.tenlong.com.tw/products/9789864345304


此篇文章同步發於個人部落格

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

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

新建一個原則 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


上一篇
修改資料表新建 migration
下一篇
我的最愛追蹤功能製作
系列文
使用 Laravel 打造 RESTful API30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言