Laravel8中介軟體組的簡單使用

bluememory發表於2022-05-07

系統相關情況:ubuntu + php7.4 + Laravel8
說明:最近在寫JWT相關邏輯,參考這篇文章配置JWT,具體怎麼配置,這裡就不說了,這篇文章主要針對token的驗證,透過中介軟體來實現。

補充一下,我的專案是兩個模組的,路由api那個我同事再用,我是後臺所以新增一個admin路由檔案,使用者體系也不同,他是user表,我是user_admin表,所以第一步先配置我的模組的資訊

第一步,配置自己的guards

在config/auth.php裡面的guards陣列新增admin鍵值:

'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'api' => [
            'driver' => 'jwt',
            'provider' => 'apiusers',
        ],
        'admin' => [ //admin模組
            'driver' => 'jwt',
            'provider' => 'admin',
        ],
    ],

然後我下面找providers陣列,新增admin模組:

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

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

        'admin' => [ //admin模組
            'driver' => 'eloquent',
            'model' => App\Models\UserAdmin::class, //admin的使用者模型
        ],
    ],

第二步,生產中介軟體

透過命令:

php artisan make:middleware AuthAdminJwt 

AuthAdminJwt類裡面內容如下:

<?php
namespace App\Http\Middleware;

use App\Models\UserAdmin;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;
use Tymon\JWTAuth\Facades\JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;

class AuthAdminJwt
{
    /**
     * @param Request $request
     * @param Closure $next
     * @return \Illuminate\Http\JsonResponse|mixed
     */
    public function handle(Request $request, Closure $next)
    {
        //配置JWTAuth::parseToken()->authenticate()讀取user_admin表,預設讀取user表
        Config::set('auth.providers.users.model', UserAdmin::class);
        try {
            if (!$user = JWTAuth::parseToken()->authenticate()) { //獲取到使用者資料,並賦值給$user
                return response()->json([
                    'code' => 1,
                    'message' => '使用者不存在'
                ], 404);
            }
            return $next($request);
        } catch (TokenExpiredException $e) {
            return response()->json([
                'code' => 1003,
                'message' => 'token已過期',
            ]);
        } catch (TokenInvalidException $e) {
            return response()->json([
                'code' => 1002,
                'message' => 'token無效',
            ]);
        } catch (JWTException $e) {
            return response()->json([
                'code' => 1001,
                'message' => '缺少token引數',
            ]);
        }
    }
}

第三步:配置路由

第一種:配置路由中介軟體屬性

(1):透過路由規則配:
在Http\Kernel.php裡面:

protected $routeMiddleware = [
        'jwt.admin.auth' => \App\Http\Middleware\AuthAdminJwt::class,
    ];

然後配置路由規則:

Route::get("/user/detail", [UserController::class, "detail"])->middleware('jwt.admin.auth');

執行這個路由,如果沒有給token,就會報錯。成功。

(2)還有一種是透過控制器配置中介軟體:
在Http\Kernel.php裡面,這個和上面一樣:

protected $routeMiddleware = [
        'jwt.admin.auth' => \App\Http\Middleware\AuthAdminJwt::class,
    ];

接著在控制器裡面的構造方法裡面:

<?php
/**
 * Created by PhpStorm.
 * User: xyf
 * Date: 2022/5/6
 * Time: 13:34
 */

namespace App\Http\Admin\Account;

use App\Http\Admin\Controller;
use App\Http\Requests\AdminLoginRequest;
use App\Models\UserAdmin;

class LoginController extends Controller
{
    public function __construct()
    {
        //除了login方法,其他需要驗證token
        $this->middleware('jwt.admin.auth', ['except' => ['login']]);
    }

    /**
     * 登入
     *
     * @param AdminLoginRequest $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function login(AdminLoginRequest $request)
    {
        $credentials = request(['mobile', 'password']);
        if (!$token = auth("admin")->attempt($credentials)) {
            return $this->fail("登入失敗");
        }

        return $this->success([
            'access_token' => $token,
            'token_type' => 'Bearer',
            'expires_in' => auth('admin')->factory()->getTTL()
        ]);
    }

    /**
     * 退出登入
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout()
    {
        auth("admin")->logout();
        return $this->success();
    }

    public function test()
    {
        return $this->success();
    }
}

第二種:配置路由中介軟體組屬性

在Http\Kernel.php裡面:

 protected $middlewareGroups = [
        'web' => [
           //.......
        ],

        'api' => [
          //......
        ],
        'admin'=>[
            \App\Http\Middleware\Auth\AuthAdminJwt::class,
        ]
    ];

或則另一種寫法:

 protected $middlewareGroups = [
        'web' => [
           //.......
        ],

        'api' => [
          //......
        ],
        'admin'=>[
              /**
              這種寫法前提是在protected $routeMiddleware = [
             'jwt.admin.auth' => \App\Http\Middleware\AuthAdminJwt::class,]配置了
             **/
          "jwt.admin.auth"
    ];
        ]
    ];

然後配置路由規則:

Route::group(['middleware' => 'admin'],function(){
    Route::post("/account/test", [LoginController::class, "test"]);
    Route::post("/account/logout", [LoginController::class, "logout"]);
});

或則另一種寫法:

Route::middleware(['admin'])->group(function (){
  Route::post("/account/test", [LoginController::class, "test"]);
  Route::post("/account/logout", [LoginController::class, "logout"]);
});

這樣你執行上面的路由就會驗證token

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章