Laravel guard 菊花守衛者

liaosp發表於2020-12-29

在這裡插入圖片描述

前言

在go-zero 文件中有句話我覺得不錯: 工具大於約定和文件 。laravel提供了很多優雅的工具,比如 門面,佇列,對於開發者來說很友好。

auth在小型專案中使用Passport就大材小用了。Laravel Passport 自定義新增Client

這篇文章主要介紹了簡單的token驗證。

開 始

新增使用者表 api_token (或者自定義,後面說)

php artisan make:migration alter_users_add_api_token

    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('api_token',200)->comment('登入token');
        });
    }

php artisan migrate

users表中新增了api_token 建立一條資料 api_token 為 :s8df78a7d8f7as78d

在路由中新增一個訪問路徑

Routephp:group(['middleware' => ['auth.api']], function () {
    Route::get('/getUser', function () {
        var_dump( Auth::user()->name);exit;
    });
});

這時訪問,會報:
在這裡插入圖片描述

說明我們這個auth.api 的這個中介軟體不存在,需要我們建立一個

php artisan make:middleware WebToken

建立一箇中介軟體WebToken

namespace App\Http\Middleware;

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

class WebToken
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        if (Auth::guard('api')->guest()) {
            return response()->json(['code' => 401,'msg' => 'token錯誤或為空']);
        }

        return $next($request);
    }
}

Kernel.php 中新增中介軟體:
在這裡插入圖片描述

這時訪問/api/getUser

提示token錯誤或為空 ,這時因為我們沒有傳入token

再嘗試訪問: /api/getUser?api_token=s8df78a7d8f7as78d

可以看到我們在路由那邊列印的 Auth::user()->name 是報錯的,但是其實它是驗證通過的。
在這裡插入圖片描述

到了這,可能很多同學會說,這個假教程,怎麼獲取不到name,取關了取關了!!!!

下面一一解釋:

這邊主要講 defaults guards providers 三個引數的作用。

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'api' => [
            'driver' => 'token',
            'provider' => 'users',
            'hash' => false,
        ],
        '菊花園守衛者' => [
            'driver' => 'token',
            'provider' => '菊花園提供者'
        ]
    ],

guards 熟稱守衛隊,也可以把它想象成保衛程式的一群守衛員,

開個玩笑:你可以想象成有一個守衛需要保護菊花園,所以我們認為他是一個菊花園守衛者,那他要守衛的物件又是誰呢?(有畫面了嗎?)

providers 裝菊花提供者,裡面可以配置對應的資料庫,很多業務場景中,(舉個?)可能有多個業務平臺需要登入管理使用者,比如:倉庫使用者放一個表,客戶使用者一個表等等~

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

        '菊花園提供者' => [
          'driver' => 'database',
          'table' => '放菊使用者表(每一個使用者都有一朵菊花)',
               ],
    ],

我們回過來看,在剛開始的時候在中介軟體中使用過guards

   if (Auth::guard('api')->guest()) {
       return response()->json(['code' => 401,'msg' => 'token錯誤或為空']);
   }

指定的守衛是 api 進行守衛

所以正確的獲取使用者資訊應該是需要告訴Auth 它目前守衛的到底是哪個使用者組:是web呢?還是api?或者是菊花呢?

Auth::guard('api')->user()->name

這樣便能獲取到姓名,有同學會說,可以不要指定的guard 獲取使用者資訊嗎?

    'defaults' => [
        'guard' => 'api',
        'passwords' => 'users',
    ],

在defaults 設定預設的guard 為api,就可以使用獲取使用者了

Auth::user()->name

可不可以資料庫不要命名為api_token叫做 access_token 呢?或者前端傳遞的時候不要是?api_token 改成 ?token 。

只需要在guards對應的守衛中新增:

        'api' => [
            'driver' => 'token',
            'provider' => 'users',
            'hash' => false,
            'input_key'=>'token',
            'storage_key'=>'access_token'
        ],
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章