怎樣在 Laravel 中處理前端認證

Epona發表於2019-07-04

在Laravel中我們可以很方便的通過策略(Policy)來進行許可權認證問題。一個簡單的例子如下:

<?php

namespace App\Policies;

use App\User;
use App\Post;

class PostPolicy
{
    /**
     * 判斷該方法能否被使用者操作。
     *
     * @param  \App\User  $user
     * @param  \App\Post  $post
     * @return bool
     */
    public function update(User $user, Post $post)
    {
        return $user->id === $post->user_id;
    }
}

上面的程式碼表示只有當前登入的使用者ID和發表文章的使用者ID一致時,才可以編輯文章。而在blade模版中可以像下面的程式碼一樣使用:

@can('update', $post)
    <button>Edit</button>
@endcan

這樣我們就完成了一個簡單的許可權處理。但是當我們使用Vue等前端框架處理的時候,我們沒有辦法使用can方法,所以,處理方式就比較麻煩了起來,下面的幾種方法是我在LaracastsFREEK.DEV上看到的解決辦法。

下面的幾個方法均假設我們已經把文章抽離成了一個Vue元件叫做blog-post.

方法一

將對應的許可權傳遞到元件中。

<blog-post :post="{{ $post }}" :canUpdate="@json(auth()->user()->can('update', $post))"></blog-post>

我們在元件內部可以通過v-if來判斷是否顯示Edit按鈕

<button v-if="canUpdate">Edit</button>

方法二

將對應的許可權包含到post資料中返回給前端

<?php

namespace App;

class Post extents Model
{

    protected $appends = ['authorizations'];

    public function getAuthorizationsAttribute()
    {
        return [
            'update' => \Gate::allows('update', $this),
            'destroy' => \Gate::allows('destroy', $this),
        ];
    }
}

在前端中我們可以直接獲取post中的資料來處理許可權問題

<button v-if="post.authorizations.update">Edit</button>

方法三

將相關的許可權儲存到資料庫中。首先在users表中加入欄位permissions,在這裡儲存許可權資訊,簡單的demo如下:

$user->permissions = ["update-post", "destroy-post"];
$user->save();

針對複雜的情況可以用到多對多的資料庫關係來儲存(實際上就是我們經常用到的許可權系統),然後在我們的blade模版頂部顯示出許可權資訊。

<script>
    window.App = {
        permissions: @json(auth()->user()->permissions)
    }
</script>

在Vue中我們通過window.App.permissions來進行許可權處理。

方法四

與方法二很相似,只不過將getAuthorizationsAttribute替換成了API資源來進行處理,具體的內容可以檢視文章底部的第二個連結。

討論

就我個人而言,由於前後端分離,我一般使用的是第二種或者是第四種方法。不知道你們碰到這種情況會怎樣處理呢?

參考

There's nothing wrong with having a little fun.

相關文章