聊聊Laravel中的攔截器(Gates)

2022-09-28 22:00:22

Laravel 9 保姆級視訊教學,想學不會都難!進入學習

Laravel Gates(攔截器)允許你授權使用者存取應用程式的某些區域。你可以輕鬆地在應用程式中定義攔截器,然後使用它們來允許或拒絕存取。

簡單範例

假設在使用者表中,有一個名為 admin 的列,根據使用者是否是管理員,它可以是 10。我們可以通過如下簡單的檢查來輕鬆保護應用程式的一部分模組:

Route::get('administration', function(){
    if(auth()->check() && auth()->user()->admin){
        echo 'Welcome to the admin section';
    } else {
        echo 'You shall not pass';
    }
});
登入後複製

如果特定使用者的 admin 行設定為 1 ,他們將看到以下輸出。

Admin access screenshot

否則,他們將看到以下內容:

Admin denied access

這看上去很棒對吧!我們有一種簡單的方法來允許或拒絕存取我們應用程式中的特定部分。然而問題是:如果整個應用程式中,有大量的位置要檢查並修改使用者存取許可權怎麼辦。我們將不得不全域性搜尋程式碼並在每個地方修改這個邏輯。效率不是很高。

對此,我們可以定義一個 Gate(攔截器)並在整個應用程式中使用它。

定義攔截器

要定義攔截器,可以開啟 App\Providers\AuthServiceProvider.php 檔案並在我們的 boot() 方法中新增以下內容:

public function boot()
{
    $this->registerPolicies();

    Gate::define('access-admin', function ($user) {
        return $user->admin;
    });
}
登入後複製

我們可以在整個應用中任何想驗證管理員使用者的地方使用這個攔截器。在下一節中,你將看到我們如何使用這個新的攔截器。

使用攔截器

要使用攔截器,我們可以呼叫 Gate::allows()Gate::denies() 方法,如下所示:

Route::get('administration', function(){
    if (Gate::allows('access-admin')) {
        echo 'Welcome to the admin section';
    } else {
        echo 'You shall not pass';
    }
});
登入後複製

請注意: Gate::denies() 方法會對 Gate::allows() 執行反向檢查

攔截器的好處是我們現在可以隨時更改我們的定義,授權邏輯會同步在整個應用程式中更改。

使用攔截器的另一個目的是檢查與資料相關的許可權。以部落格為例,我們可以授予使用者對他們建立的貼文的編輯許可權。

我們可以將資料傳遞給攔截器以檢查使用者是否有權執行某項操作。

像攔截器傳遞資料

假設我們的應用程式有一個 Post 表,其中有一列 user_id,其中包含建立它的使用者的 ID。我們可以定義一個 Gate(攔截器)來確定使用者是否可以像這樣編輯特定的貼文:

Gate::define('edit-post', function ($user, $post) {
    return $user->id === $post->user_id;
});
登入後複製

兩個引數被傳遞給我們的攔截器定義。第一個是 $user 物件,其中包含經過身份驗證的使用者,第二個引數是我們的 $post 物件。

小Tips:如果沒有經過身份驗證的使用者,攔截器將返回 false。

如果經過身份驗證的使用者是原始作者,攔截器將允許存取;否則將拒絕存取。

下面是一個快速範例,說明我們如何使用新的 edit-post 攔截器。

Route::get('edit/{id}', function($id){

    $post = \App\Model\Post::find($id);

    if( Gate::allows('edit-post', $post) ){
        echo 'You can edit this post';
    } else {
        echo 'You shall not pass';
    }

});
登入後複製

上面,我們在範例中使用了 Route Closures,但我們可能希望將此路由對映到控制器。這也將讓我們使用新的 Authorize 函數。

Authorize 授權助手函數

除了效率之外,使用攔截器的另一個原因是輔助函數。

假設我們將路由對映到控制器:

Route::get('edit/{id}', 'PostController@edit');
登入後複製

我們可以使用 authorize() 助手來檢查經過身份驗證的使用者是否有權編輯貼文:

<?php

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    public function edit($id){

        $post = Post::find($id);
        $this->authorize('edit-post', $post);

    }
}
登入後複製

如果控制器從 App\Http\Controllers\Controller 基礎類別繼承而來,你可以像使用 Gate::allow() 函數一樣使用 authorize() 助手函數。

最後,如果我們想在檢視中檢查授權怎麼辦?我們可以使用 @can Blade 函數助手來做到這一點。

在檢視層進行鑑權

假設 Blade 檢視如下:




    
    
    {{ $post->title }}


    

{{ $post->title }}

{!! $post->body !!}

登入後複製

我們可以使用 Blade 助手函數 @can 檢查當前使用者是否被允許編輯這篇文章:




    
    
    {{ $post->title }}


    

{{ $post->title }}

{!! $post->body !!}

@can('edit-post', $post) Edit Post @endcan
登入後複製

如果經過身份驗證的使用者是該貼文的原始作者,他們將看到一個編輯貼文按鈕。

使用 @can 助手函數可以使我們的程式碼更易於閱讀和管理。你也可以使用 @cannot 作反向操作。

小結

這是在 Laravel 應用程式中使用 Gates(攔截器)的基礎知識。攔截器允許我們輕鬆授權特定使用者存取我們的應用程式區域。這也可以稱為存取控制列表 (ACL),即與物件關聯的許可權列表。

但是我們不應該使事情過於複雜......在最簡單的場景中,攔截器 用於允許或拒絕存取。使用者既可以被允許授權,同時也可以被拒絕授權。

因為本教學是關於讓使用者通過而不是通過......所以有必要用這張來自指環王的甘道夫影象送你出去(手動狗頭)。

shall-not-pass.jpg

要了解有關 Laravel Gates(攔截器)的更多資訊,請務必存取 Larave 授權相關的檔案。

英文原文地址:https://devdojo.com/tnylea/laravel-gates

譯文地址:https://learnku.com/laravel/t/67585

【相關推薦:】

以上就是聊聊Laravel中的攔截器(Gates)的詳細內容,更多請關注TW511.COM其它相關文章!