久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長(zhǎng)資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      一文徹底弄清Laravel Guards的使用

      Laravel有一個(gè)最常見(jiàn)的功能,即對(duì)持久用戶進(jìn)行身份驗(yàn)證,在這種情況下, 這些功能存儲(chǔ)在任何受支持的數(shù)據(jù)庫(kù) (MySQL, SQLite 等),當(dāng)你考慮到你可以在幾分鐘內(nèi)設(shè)置一個(gè)web應(yīng)用程序并使用忘記的密碼和所有的調(diào)整進(jìn)行用戶身份驗(yàn)證時(shí),這個(gè)東西是令人驚嘆的。當(dāng)你需要更復(fù)雜的東西時(shí)會(huì)發(fā)生什么?

      例如,如果您需要擁有自己的身份驗(yàn)證門戶的多個(gè)用戶類型,該怎么辦?這些不同類型的用戶可以是客戶、銷售商和管理員。這樣的機(jī)制可能很快就會(huì)變得非?;靵y,我知道,因?yàn)槲以?jīng)經(jīng)歷過(guò)。我們通常預(yù)先計(jì)劃數(shù)據(jù)庫(kù)的結(jié)構(gòu),但不構(gòu)建我們的身份驗(yàn)證流程和機(jī)制的樣子。

      推薦:《laravel教程》

      在本文中,我希望分解并解釋如何處理這些場(chǎng)景。

      什么是 Guards?

      Laravel 中的 Guards 是一種機(jī)制,您的應(yīng)用程序可以通過(guò)它知道某人甚至某事是否經(jīng)過(guò)身份驗(yàn)證。當(dāng)我們查看 Laravel 的默認(rèn)安裝時(shí),我們通常會(huì)看到一個(gè)守衛(wèi),即 web。當(dāng)訪問(wèn)者通過(guò)此防護(hù)進(jìn)行身份驗(yàn)證時(shí),任何使用 auth 中間件都將允許用戶通過(guò)查看頁(yè)面,這是因?yàn)殚_(kāi)箱即用的默認(rèn)防護(hù)始終是 web。如果一個(gè)人正在瀏覽并且在任何時(shí)候都沒(méi)有經(jīng)過(guò)身份驗(yàn)證,那么他們?cè)谠撌匦l(wèi)中被稱為訪客。

      通常,當(dāng)向 Web 應(yīng)用程序添加額外的防護(hù)時(shí),它會(huì)為 API 提供不同的身份驗(yàn)證機(jī)制,例如用戶令牌。不過(guò),這個(gè)默認(rèn)守衛(wèi)不必是您應(yīng)用程序中唯一的 Web 守衛(wèi)。事實(shí)上,我們可以為不同的用戶類型設(shè)置一個(gè) Guard,即使是那些不使用傳統(tǒng)用戶名和密碼進(jìn)行身份驗(yàn)證的用戶。

      如何為 Eloquent 提供程序創(chuàng)建新的 Authenticatable?

      為了演示如何創(chuàng)建一個(gè)新的 Authenticatable,我們將使用一個(gè)頁(yè)面示例,訂單的客戶可以通過(guò)該頁(yè)面進(jìn)行身份驗(yàn)證。 客戶只能使用簽名 URL 對(duì)應(yīng)用程序進(jìn)行身份驗(yàn)證,一旦通過(guò)身份驗(yàn)證,他們就可以執(zhí)行其他操作,例如取消訂單。

      首先,我們創(chuàng)建一個(gè)新模型:

      php artisan make:model Order

      現(xiàn)在,我們需要修改 app/Models/Order.php 中的 Order 模型,添加一些 interfacestraits。 這滿足 Order 模型可用于守衛(wèi)和 Eloquent 提供者類型。

      Order.php

      <?php  namespace AppModels;  use IlluminateAuthAuthenticatable; use IlluminateAuthMustVerifyEmail; use IlluminateContractsAuthAccessAuthorizable as AuthorizableContract; use IlluminateContractsAuthAuthenticatable as AuthenticatableContract; use IlluminateDatabaseEloquentModel; use IlluminateDatabaseEloquentRelationsBelongsTo; use IlluminateFoundationAuthAccessAuthorizable;  class Order extends Model implements     AuthenticatableContract,     AuthorizableContract {     use Authenticatable;     use Authorizable;     use MustVerifyEmail;      public function user(): BelongsTo     {         return $this->belongsTo(User::class);     } }

      請(qǐng)注意,與開(kāi)箱即用的 User 模型相比,我們可以簡(jiǎn)單地?cái)U(kuò)展框架的 User 類,但由于我們不打算使用密碼,所以我們將忽略能夠重置其密碼的模型。

      完成此操作后,我們需要將我們的保護(hù)添加到 configs/auth.php 中的 auth 配置中。 因?yàn)槲覀円彩褂貌煌哪P停晕覀冃枰獙?shí)現(xiàn)一個(gè)附加提供程序,我們將其稱為訂單提供程序,由客戶守衛(wèi)使用。

      auth.php

      <?php return [     // auth.php 配置的其余部分      'guards' => [         'web' => [             'driver' => 'session',             'provider' => 'users',         ],          'customer' => [             'driver' => 'session',             'provider' => 'orders',         ],     ],      // auth.php 配置的其余部分     'providers' => [         'users' => [             'driver' => 'eloquent',             'model' => AppModelsUser::class,         ],          'orders' => [             'driver' => 'eloquent',             'model' => AppModelsOrder::class,         ],          // 'users' => [         //     'driver' => 'database',         //     'table' => 'users',         // ],     ], ];

      就是這樣,我們的新守衛(wèi)現(xiàn)在已經(jīng)通過(guò)了身份驗(yàn)證,但是我們需要一個(gè)機(jī)制來(lái)驗(yàn)證訪問(wèn)者,而不需要輸入密碼。

      身份驗(yàn)證是否需要密碼?

      從技術(shù)上講,是的, 身份驗(yàn)證需要密碼,因?yàn)樗荓ighmateContractsAuthAuthenticatable接口的一部分,該接口需要getAuthPassword()的實(shí)現(xiàn)。在前面的示例中,我們使用了Authenticatable特征來(lái)提供實(shí)現(xiàn)。不過(guò),只有當(dāng)我們嘗試使用守衛(wèi)的嘗試方法時(shí),才會(huì)使用此代碼,而我們不會(huì)使用此方法。

      在這種情況下,我們沒(méi)有計(jì)劃通過(guò)電子郵件和密碼來(lái)驗(yàn)證我們的訂單,所以我們不必?fù)?dān)心這一點(diǎn)。取而代之的是,我們將簡(jiǎn)單地創(chuàng)建一個(gè)新的中間件 組件,它將處理來(lái)自簽名的URL的身份驗(yàn)證,只有我們的應(yīng)用程序才能生成該URL供賣家提供給客戶。

      首先,我們將在routes/web.php中為我們的訂單設(shè)置一個(gè)示例路由。

      web.php

      <?php  use IlluminateSupportFacadesRoute;  Route::get('order/{order}', function (AppModelsOrder $order) {     return view('order.view', ['order' => $order]); })     ->name('order.view')     ->middleware([         'auth.signed:order,customer',         'auth:customer,seller',     ]);

      請(qǐng)注意,我們已經(jīng)添加了一個(gè)經(jīng)過(guò)身份驗(yàn)證的中間件。它還不存在,所以我們必須創(chuàng)建一個(gè)并將其添加到http內(nèi)核。我們可以使用以下命令創(chuàng)建中間件:

      php artisan make:middleware AuthenticateWhenRequestIsSigned

      這將創(chuàng)建app/Http/Middleware/AuthenticateWhenRequestIsSigned.php文件,我們可以編輯該文件。我們將向Handle方法添加兩個(gè)參數(shù),這兩個(gè)參數(shù)將是要從路由和我們想要進(jìn)行身份驗(yàn)證的守衛(wèi)中使用的參數(shù)名稱。然后,Handle方法的代碼非常簡(jiǎn)單,如果請(qǐng)求已簽名,則使用Order參數(shù)中的ID值對(duì)客戶進(jìn)行身份驗(yàn)證。

      AuthenticateWhenRequestIsSigned.php

      <?php  namespace AppHttpMiddleware;  use Closure; use IlluminateHttpRequest; use IlluminateSupportFacadesAuth;  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);     } }

      現(xiàn)在我們已經(jīng)創(chuàng)建了中間件,我們需要在內(nèi)核中注冊(cè)它。

      Kernel.php

      <?php  namespace AppHttp;  use IlluminateFoundationHttpKernel as HttpKernel;  class Kernel extends HttpKernel {     // Http內(nèi)核的其余部分      /**      * 應(yīng)用程序的路由中間件。      *      * 這些中間件可以分配到組中,也可以單獨(dú)使用。      *      * @var array      */     protected $routeMiddleware = [         // 數(shù)組的其余部分         'auth.signed' => AppHttpMiddlewareAuthenticateWhenRequestIsSigned::class,         // 數(shù)組的其余部分     ];      // Http內(nèi)核的其余部分 }

      這樣做不會(huì)使中間件工作,因?yàn)槲覀冞€將身份驗(yàn)證中間件用于我們的路由,這意味著身份驗(yàn)證簽名的中間件永遠(yuǎn)不會(huì)執(zhí)行,因?yàn)樯矸蒡?yàn)證中間件具有優(yōu)先級(jí),并且將在簽名中間件有機(jī)會(huì)對(duì)客戶進(jìn)行身份驗(yàn)證之前終止請(qǐng)求。

      要解決這個(gè)問(wèn)題,我們只需要向內(nèi)核添加一個(gè)額外的數(shù)組,以設(shè)置在會(huì)話啟動(dòng)中間件之后運(yùn)行的身份驗(yàn)證簽名中間件的優(yōu)先級(jí)。

      Kernel.php

      <?php  namespace AppHttp;  use IlluminateFoundationHttpKernel as HttpKernel;  class Kernel extends HttpKernel {     // HTTP內(nèi)核的其余部分      /**      * 中間件的優(yōu)先級(jí)排序列表。      *      * 強(qiáng)制非全局中間件始終處于給定順序。      *      * @var string[]      */     protected $middlewarePriority = [         IlluminateCookieMiddlewareEncryptCookies::class,         IlluminateSessionMiddlewareStartSession::class,         IlluminateViewMiddlewareShareErrorsFromSession::class,         AppHttpMiddlewareAuthenticateWhenRequestIsSigned::class,         IlluminateContractsAuthMiddlewareAuthenticatesRequests::class,         IlluminateRoutingMiddlewareThrottleRequests::class,         IlluminateRoutingMiddlewareThrottleRequestsWithRedis::class,         IlluminateSessionMiddlewareAuthenticateSession::class,         IlluminateRoutingMiddlewareSubstituteBindings::class,         IlluminateAuthMiddlewareAuthorize::class,     ]; }

      我們可以通過(guò)向內(nèi)核添加midlewarePriority屬性來(lái)實(shí)現(xiàn)這一點(diǎn),覆蓋父級(jí)Kernel。在AuthenticatesRequests中間件和StartSession中間件之前這樣做意味著,當(dāng)URL中提供有效簽名時(shí),中間件可以對(duì)客戶進(jìn)行身份驗(yàn)證。

      現(xiàn)在,每當(dāng)訪問(wèn)者使用帶有有效簽名的url登陸該頁(yè)面時(shí),他們將通過(guò)我們的守衛(wèi)進(jìn)行身份驗(yàn)證,并能夠在沒(méi)有簽名的情況下重新訪問(wèn)該url,直到他們的會(huì)話超時(shí)。不過(guò),這仍然有一個(gè)問(wèn)題,任何這樣做的客戶也不僅能夠查看他們的訂單,還可以通過(guò)簡(jiǎn)單地更改URL中的id來(lái)查看任何訂單。請(qǐng)記住,Authentication不是Authorization,這意味著為了保護(hù)客戶的其他訂單,我們需要添加一些授權(quán)。

      我們?nèi)绾伪Wo(hù)客戶只看到一個(gè)訂單?

      這是一個(gè)相當(dāng)簡(jiǎn)單的程序。我們現(xiàn)在只需要一個(gè)策略,但在本例中,我們需要使用guard參數(shù)作為policy make命令的一部分。這將允許我們生成我們需要的大部分代碼。

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

      現(xiàn)在,由于模型和可驗(yàn)證的匹配,我們需要重命名幾個(gè)方法的參數(shù),并為這些方法分配一個(gè)返回值,這將允許訂單只查看和更新它自己。我們需要繼續(xù)編輯app/policies/customerOrderPolicy.php。我們實(shí)現(xiàn)了用于updatingviewing單個(gè)訂單的方法,其余的可以返回false。

      CustomerOrderPolicy.php

      <?php  namespace AppPolicies;  use AppModelsOrder; use IlluminateAuthAccessHandlesAuthorization;  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;     } }

      一旦我們完成了這一點(diǎn),我們只需要注冊(cè)策略并將中間件添加到路由中。現(xiàn)在,當(dāng)經(jīng)過(guò)身份驗(yàn)證的用戶試圖訪問(wèn)除他們自己的訂單之外的任何訂單時(shí),他們都將失敗。這樣,我們就通過(guò)對(duì)用戶的身份驗(yàn)證和授權(quán)保護(hù)了應(yīng)用程序。

      AuthServiceProvider.php

      <?php  namespace AppProviders;  use AppModelsOrder; use AppPoliciesCustomerOrderPolicy; use IlluminateFoundationSupportProvidersAuthServiceProvider as ServiceProvider; use IlluminateSupportFacadesGate;  class AuthServiceProvider extends ServiceProvider {     /**      * 應(yīng)用程序的策略映射.      *      * @var array      */     protected $policies = [         Order::class => CustomerOrderPolicy::class,     ];      // AuthServiceProvider 的其余部分 }

      現(xiàn)在,我們通過(guò)配置路由查看訂單的策略。

      web.php

      <?php  use IlluminateSupportFacadesRoute;  Route::get('order/{order}', function (AppModelsOrder $order) {     return view('order.view', ['order' => $order]); })     ->name('order.view')     ->middleware([         'auth.signed:order,customer',         'auth:customer,seller',         'can:view,order'     ]);

      將 Web Guard 重命名為更具描述性的東西有多難?

      只有當(dāng)我們也有一名稱為賣家的守衛(wèi)時(shí),讓一名稱為客戶的守衛(wèi)才真正有意義,他們?nèi)匀粫?huì)使用電子郵件和密碼進(jìn)行身份驗(yàn)證,為客戶生成訂單。我們已經(jīng)有了 web 守衛(wèi),但這并不是真正適合所有的 web 用戶,而是為賣家準(zhǔn)備的,所以我們會(huì)相應(yīng)地給它命名。

      重命名默認(rèn)守衛(wèi)可能會(huì)變得很棘手,特別是在其他中間件和包(如Laravel Sanctum和Fortify)將按名稱使用 Web 守衛(wèi)的情況下。幸運(yùn)的是,這兩個(gè)包都有配置選項(xiàng),可以輕松地更改這一點(diǎn)。

      首先,我們必須編輯 configs/auth.php 以擁有一個(gè)名為賣家的守衛(wèi)。然后,我們還需要更新默認(rèn)值以反映名稱更改。

      auth.php

      <?php return [     // auth.php 其余的配置部分      'guards' => [         'web' => [             'driver' => 'session',             'provider' => 'users',         ],          'customer' => [             'driver' => 'session',             'provider' => 'orders',         ],     ],      // auth.php 其余的配置部分      'providers' => [         'users' => [             'driver' => 'eloquent',             'model' => AppModelsUser::class,         ],          'orders' => [             'driver' => 'eloquent',             'model' => AppModelsOrder::class,         ],          // 'users' => [         //     'driver' => 'database',         //     'table' => 'users',         // ],     ], ];

      如果我們還使用 FortifySanctum 那么每個(gè)配置都需要設(shè)置一個(gè) guard ,該值將為這些包配置保護(hù). 之后就可以使用了. 需要用 auth:seller 替代 auth:web 更新路由 。

      結(jié)論

      與 Guards 一起工作一開(kāi)始可能會(huì)有點(diǎn)混亂,在做出長(zhǎng)期決定之前肯定需要一些探索。我曾在多個(gè)項(xiàng)目中工作過(guò),在這些項(xiàng)目中,分離警衛(wèi)既是有益的,也是一種負(fù)擔(dān)。通常,處理這種情況的最佳方法是構(gòu)建一個(gè)快速原型,說(shuō)明如何處理某些分離。通常,在決定訪問(wèn)者是否可以訪問(wèn)網(wǎng)站的特定部分時(shí),使用 Gate 是一個(gè)更好的選擇。

      我已經(jīng)簡(jiǎn)單介紹了本文中的所有步驟,如果您希望進(jìn)行

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)