搜尋
首頁php框架Laravel一文徹底弄清楚Laravel Guards的使用

Laravel有一個最常見的功能,即對持久用戶進行身份驗證,在這種情況下, 這些功能存儲在任何受支持的數據庫(MySQL, SQLite 等),當你考慮到你可以在幾分鐘內設定一個web應用程式並使用忘記的密碼和所有的調整進行用戶身份驗證時,這個東西是令人驚嘆的。當你需要更複雜的東西時會發生什麼?

例如,如果您需要擁有自己的身份驗證入口網站的多個使用者類型,該怎麼辦?這些不同類型的使用者可以是客戶、銷售商和管理員。這樣的機制可能很快就會變得非常混亂,我知道,因為我曾經經歷過。我們通常會預先規劃資料庫的結構,但不會建構我們的身份驗證流程和機制的樣子。

推薦:《laravel教學

在本文中,我希望分解並解釋如何處理這些場景。

什麼是 Guards?

Laravel 中的 Guards 是一種機制,您的應用程式可以透過它知道某人甚至某事是否經過身份驗證。當我們查看 Laravel 的預設安裝時,我們通常會看到一個守衛,即 web。當訪客透過此防護進行身份驗證時,任何使用 auth 中間件都將允許使用者透過查看頁面,這是因為開箱即用的預設防護始終是 web。如果一個人正在瀏覽並且在任何時候都沒有經過身份驗證,那麼他們在該守衛中被稱為訪客。

通常,當在 Web 應用程式中新增額外的防護時,它會為 API 提供不同的驗證機制,例如使用者令牌。不過,這個預設守衛不必是您應用程式中唯一的 Web 守衛。事實上,我們可以為不同的使用者類型設定一個 Guard,即使是那些不使用傳統使用者名稱和密碼進行身份驗證的使用者。

如何為 Eloquent 提供者建立新的 Authenticatable?

為了示範如何建立一個新的 Authenticatable,我們將使用一個頁面範例,訂單的客戶可以透過該頁面進行驗證。客戶只能使用簽名 URL 對應用程式進行身份驗證,一旦通過身份驗證,他們就可以執行其他操作,例如取消訂單。

首先,我們建立一個新模型:

php artisan make:model Order

現在,我們需要修改app/Models/Order.php 中的Order 模型,加入一些interfaces traits。這滿足 Order 模型可用於守衛和 Eloquent 提供者類型。

Order.php

<?php namespace App\Models;

use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\MustVerifyEmail;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Foundation\Auth\Access\Authorizable;

class Order extends Model implements
    AuthenticatableContract,
    AuthorizableContract
{
    use Authenticatable;
    use Authorizable;
    use MustVerifyEmail;

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }
}

請注意,與開箱即用的User 模型相比,我們可以簡單地擴展框架的User類,但由於我們不打算使用密碼,所以我們將忽略能夠重置其密碼的模型。

完成此操作後,我們需要將我們的保護加入到 configs/auth.php 中的 auth 配置中。因為我們也使用不同的模型,所以我們需要實現一個附加提供程序,我們稱之為訂單提供程序,由客戶守衛使用。

auth.php

<?php return [
    // auth.php 配置的其余部分

    &#39;guards&#39; => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'customer' => [
            'driver' => 'session',
            'provider' => 'orders',
        ],
    ],

    // auth.php 配置的其余部分
    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],

        'orders' => [
            'driver' => 'eloquent',
            'model' => App\Models\Order::class,
        ],

        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],
    ],
];

就是這樣,我們的新守衛現在已經通過了身份驗證,但是我們需要一個機制來驗證訪問者,而不需要輸入密碼。

身份驗證是否需要密碼?

從技術上講,是的, 身份驗證需要密碼,因為它是Lighmate\Contracts\Auth\Authenticatable介面的一部分,此介面需要getAuthPassword()的實作。在前面的範例中,我們使用了Authenticatable特徵來提供實作。不過,只有當我們嘗試使用守衛的嘗試方法時,才會使用此程式碼,而我們不會使用此方法。

在這種情況下,我們沒有計劃透過電子郵件和密碼來驗證我們的訂單,所以我們不必擔心這一點。取而代之的是,我們將簡單地創建一個新的中間件 元件,它將處理來自簽署的URL的身份驗證,只有我們的應用程式才能產生該URL供賣家提供給客戶。

首先,我們將在routes/web.php中為我們的訂單設定一個範例路由。

web.php

<?php use Illuminate\Support\Facades\Route;

Route::get(&#39;order/{order}&#39;, function (\App\Models\Order $order) {
    return view(&#39;order.view&#39;, [&#39;order&#39; => $order]);
})
    ->name('order.view')
    ->middleware([
        'auth.signed:order,customer',
        'auth:customer,seller',
    ]);

請注意,我們已經新增了一個經過驗證的中間件。它還不存在,所以我們必須創建一個並將其添加到http內核。我們可以使用以下命令建立中間件:

php artisan make:middleware AuthenticateWhenRequestIsSigned

这将创建app/Http/Middleware/AuthenticateWhenRequestIsSigned.php文件,我们可以编辑该文件。我们将向Handle方法添加两个参数,这两个参数将是要从路由和我们想要进行身份验证的守卫中使用的参数名称。然后,Handle方法的代码非常简单,如果请求已签名,则使用Order参数中的ID值对客户进行身份验证。

AuthenticateWhenRequestIsSigned.php

<?php namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class AuthenticateWhenRequestIsSigned
{
    public function handle(Request $request, Closure $next, string $parameterName, string $guard = null)
    {
        if ($request->hasValidSignature()) {
            if (Auth::guard($guard)->check()) {
                Auth::guard($guard)->logout();
            }
            Auth::guard($guard)->loginUsingId($request->route()->parameter($parameterName));
        }

        return $next($request);
    }
}

现在我们已经创建了中间件,我们需要在内核中注册它。

Kernel.php

<?php namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    // Http内核的其余部分

    /**
     * 应用程序的路由中间件。
     *
     * 这些中间件可以分配到组中,也可以单独使用。
     *
     * @var array
     */
    protected $routeMiddleware = [
        // 数组的其余部分
        &#39;auth.signed&#39; => \App\Http\Middleware\AuthenticateWhenRequestIsSigned::class,
        // 数组的其余部分
    ];

    // Http内核的其余部分
}

这样做不会使中间件工作,因为我们还将身份验证中间件用于我们的路由,这意味着身份验证签名的中间件永远不会执行,因为身份验证中间件具有优先级,并且将在签名中间件有机会对客户进行身份验证之前终止请求。

要解决这个问题,我们只需要向内核添加一个额外的数组,以设置在会话启动中间件之后运行的身份验证签名中间件的优先级。

Kernel.php

<?php namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    // HTTP内核的其余部分

    /**
     * 中间件的优先级排序列表。
     *
     * 强制非全局中间件始终处于给定顺序。
     *
     * @var string[]
     */
    protected $middlewarePriority = [
        \Illuminate\Cookie\Middleware\EncryptCookies::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\AuthenticateWhenRequestIsSigned::class,
        \Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests::class,
        \Illuminate\Routing\Middleware\ThrottleRequests::class,
        \Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class,
        \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
        \Illuminate\Auth\Middleware\Authorize::class,
    ];
}

我们可以通过向内核添加midlewarePriority属性来实现这一点,覆盖父级Kernel。在AuthenticatesRequests中间件和StartSession中间件之前这样做意味着,当URL中提供有效签名时,中间件可以对客户进行身份验证。

现在,每当访问者使用带有有效签名的url登陆该页面时,他们将通过我们的守卫进行身份验证,并能够在没有签名的情况下重新访问该url,直到他们的会话超时。不过,这仍然有一个问题,任何这样做的客户也不仅能够查看他们的订单,还可以通过简单地更改URL中的id来查看任何订单。请记住,Authentication不是Authorization,这意味着为了保护客户的其他订单,我们需要添加一些授权。

我们如何保护客户只看到一个订单?

这是一个相当简单的程序。我们现在只需要一个策略,但在本例中,我们需要使用guard参数作为policy make命令的一部分。这将允许我们生成我们需要的大部分代码。

php artisan make:policy --guard customer --model App/Models/Order CustomerOrderPolicy

现在,由于模型和可验证的匹配,我们需要重命名几个方法的参数,并为这些方法分配一个返回值,这将允许订单只查看和更新它自己。我们需要继续编辑app/policies/customerOrderPolicy.php。我们实现了用于updatingviewing单个订单的方法,其余的可以返回false。

CustomerOrderPolicy.php

<?php namespace App\Policies;

use App\Models\Order;
use Illuminate\Auth\Access\HandlesAuthorization;

class CustomerOrderPolicy
{
    use HandlesAuthorization;

    public function viewAny(Order $order)
    {
        return false;
    }

    public function view(Order $customer, Order $order)
    {
        return $customer->is($order);
    }

    public function create(Order $order)
    {
        return false;
    }

    public function update(Order $customer, Order $order)
    {
        return $customer->is($order);
    }

    public function delete(Order $customer, Order $order)
    {
        return false;
    }

    public function restore(Order $customer, Order $order)
    {
        return false;
    }

    public function forceDelete(Order $customer, Order $order)
    {
        return false;
    }
}

一旦我们完成了这一点,我们只需要注册策略并将中间件添加到路由中。现在,当经过身份验证的用户试图访问除他们自己的订单之外的任何订单时,他们都将失败。这样,我们就通过对用户的身份验证和授权保护了应用程序。

AuthServiceProvider.php

<?php namespace App\Providers;

use App\Models\Order;
use App\Policies\CustomerOrderPolicy;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * 应用程序的策略映射.
     *
     * @var array
     */
    protected $policies = [
        Order::class => CustomerOrderPolicy::class,
    ];

    // AuthServiceProvider 的其余部分
}

现在,我们通过配置路由查看订单的策略。

web.php

<?php use Illuminate\Support\Facades\Route;

Route::get(&#39;order/{order}&#39;, function (\App\Models\Order $order) {
    return view(&#39;order.view&#39;, [&#39;order&#39; => $order]);
})
    ->name('order.view')
    ->middleware([
        'auth.signed:order,customer',
        'auth:customer,seller',
        'can:view,order'
    ]);

将 Web Guard 重命名为更具描述性的东西有多难?

只有当我们也有一名称为卖家的守卫时,让一名称为客户的守卫才真正有意义,他们仍然会使用电子邮件和密码进行身份验证,为客户生成订单。我们已经有了 web 守卫,但这并不是真正适合所有的 web 用户,而是为卖家准备的,所以我们会相应地给它命名。

重命名默认守卫可能会变得很棘手,特别是在其他中间件和包(如Laravel Sanctum和Fortify)将按名称使用 Web 守卫的情况下。幸运的是,这两个包都有配置选项,可以轻松地更改这一点。

首先,我们必须编辑 configs/auth.php 以拥有一个名为卖家的守卫。然后,我们还需要更新默认值以反映名称更改。

auth.php

<?php return [
    // auth.php 其余的配置部分

    &#39;guards&#39; => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'customer' => [
            'driver' => 'session',
            'provider' => 'orders',
        ],
    ],

    // auth.php 其余的配置部分

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],

        'orders' => [
            'driver' => 'eloquent',
            'model' => App\Models\Order::class,
        ],

        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],
    ],
];

如果我们还使用 Fortify 和 Sanctum 那么每个配置都需要设置一个 guard ,该值将为这些包配置保护. 之后就可以使用了. 需要用 auth:seller 替代 auth:web 更新路由 。

结论

与 Guards 一起工作一开始可能会有点混乱,在做出长期决定之前肯定需要一些探索。我曾在多个项目中工作过,在这些项目中,分离警卫既是有益的,也是一种负担。通常,处理这种情况的最佳方法是构建一个快速原型,说明如何处理某些分离。通常,在决定访问者是否可以访问网站的特定部分时,使用 Gate  是一个更好的选择。

我已经简单介绍了本文中的所有步骤,如果您希望进行更多的实验或了解此工作流的实际工作方式,您可以从 github repository 克隆设置好的代码,在演示代码中包含了一个测试,如果您想进一步进行实验,可以使用它。

原文網址:https://dev.to/slyfirefox/laravel-authentication-understanding-guards-and-implementing-authenticatables-2364

翻譯網址:https://learnku.com /laravel/t/63367

以上是一文徹底弄清楚Laravel Guards的使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:learnku。如有侵權,請聯絡admin@php.cn刪除
Laravel的主要功能:後端開發Laravel的主要功能:後端開發Apr 15, 2025 am 12:14 AM

Laravel在後端開發中的核心功能包括路由系統、EloquentORM、遷移功能、緩存系統和隊列系統。 1.路由系統簡化了URL映射,提高了代碼組織和維護性。 2.EloquentORM提供了面向對象的數據操作,提升了開發效率。 3.遷移功能通過版本控制管理數據庫結構,確保一致性。 4.緩存系統減少數據庫查詢,提升響應速度。 5.隊列系統有效處理大規模數據,避免阻塞用戶請求,提升整體性能。

Laravel的後端功能:數據庫,邏輯等等Laravel的後端功能:數據庫,邏輯等等Apr 14, 2025 am 12:04 AM

Laravel在後端開發中表現強大,通過EloquentORM簡化數據庫操作,控制器和服務類處理業務邏輯,並提供隊列、事件等功能。 1)EloquentORM通過模型映射數據庫表,簡化查詢。 2)業務邏輯在控制器和服務類中處理,提高模塊化和可維護性。 3)其他功能如隊列系統幫助處理複雜需求。

Laravel的多功能性:從簡單站點到復雜系統Laravel的多功能性:從簡單站點到復雜系統Apr 13, 2025 am 12:13 AM

選擇Laravel開發項目是因為其靈活性和強大功能適應不同規模和復雜度的需求。 Laravel提供路由系統、EloquentORM、Artisan命令行等功能,支持從簡單博客到復雜企業級系統的開發。

Laravel(PHP)與Python:開發環境和生態系統Laravel(PHP)與Python:開發環境和生態系統Apr 12, 2025 am 12:10 AM

Laravel和Python在開發環境和生態系統上的對比如下:1.Laravel的開發環境簡單,僅需PHP和Composer,提供了豐富的擴展包如LaravelForge,但擴展包維護可能不及時。 2.Python的開發環境也簡單,僅需Python和pip,生態系統龐大,涵蓋多個領域,但版本和依賴管理可能複雜。

Laravel和後端:為Web應用程序提供動力邏輯Laravel和後端:為Web應用程序提供動力邏輯Apr 11, 2025 am 11:29 AM

Laravel是如何在後端邏輯中發揮作用的?它通過路由系統、EloquentORM、認證與授權、事件與監聽器以及性能優化來簡化和增強後端開發。 1.路由系統允許定義URL結構和請求處理邏輯。 2.EloquentORM簡化數據庫交互。 3.認證與授權系統便於用戶管理。 4.事件與監聽器實現松耦合代碼結構。 5.性能優化通過緩存和隊列提高應用效率。

為什麼Laravel如此受歡迎?為什麼Laravel如此受歡迎?Apr 02, 2025 pm 02:16 PM

Laravel受歡迎的原因包括其簡化開發過程、提供愉快的開發環境和豐富的功能。 1)它吸收了RubyonRails的設計理念,結合PHP的靈活性。 2)提供瞭如EloquentORM、Blade模板引擎等工具,提高開發效率。 3)其MVC架構和依賴注入機制使代碼更加模塊化和可測試。 4)提供了強大的調試工具和性能優化方法,如緩存系統和最佳實踐。

django或laravel哪個更好?django或laravel哪個更好?Mar 28, 2025 am 10:41 AM

Django和Laravel都是全棧框架,Django適合Python開發者和復雜業務邏輯,Laravel適合PHP開發者和優雅語法。 1.Django基於Python,遵循“電池齊全”哲學,適合快速開發和高並發。 2.Laravel基於PHP,強調開發者體驗,適合小型到中型項目。

哪個是更好的PHP或Laravel?哪個是更好的PHP或Laravel?Mar 27, 2025 pm 05:31 PM

PHP和Laravel不是直接可比的,因為Laravel是基於PHP的框架。 1.PHP適合小型項目或快速原型開發,因其簡單直接。 2.Laravel適合大型項目或高效開發,因其提供豐富功能和工具,但學習曲線較陡,性能可能不如純PHP。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中