需求如下
同一個使用者有兩種角色,分別定義了是否可以禁止登陸即凍結。
應用登陸時,需要選擇角色,然後才點選登陸按鈕。
當後臺設定該使用者的某個角色凍結時,需要禁止該角色使用我們的應用程式。
解決思路
1、登陸時,在token的自定義資料中指明角色型別。
2、每當任何一個請求到來時,都檢查token中儲存的角色型別,然後都到角色表查資料庫一次,如果此人此角色被禁止,就返回錯誤。
3、本方案的缺點是:每次請求都需查一次資料庫,但這是應產品的要求,只要後臺設定凍結,就立刻禁止使用者使用。其實也有其他方案,本文是比較簡單、快捷、有效的一種。
4、另外,本文使用的是廣受好評的 tymon/jwt-auth
表結構
表:有使用者表,有角色表。
角色表欄位:使用者 id(user_id),角色 type(role_type),是否凍結(is_valid)。
解決步驟1:新增User模型類的兩個子類
比如建立 UserType1 這個類
額外說明,這裡程式碼裡的 role_type 這個鍵是自己起名字的,不需要和表中欄位一致。但值需要表示正確的角色型別 role_type。
namespace App\Models;
use Tymon\JWTAuth\Contracts\JWTSubject;
class UserType1 extends User implements JWTSubject
{
public function getJWTCustomClaims()
{
return ['role_type'=>1];
}
}
再建立 UserType2 這個類
namespace App\Models;
use Tymon\JWTAuth\Contracts\JWTSubject;
class UserType2 extends User implements JWTSubject
{
public function getJWTCustomClaims()
{
return ['role_type'=>2];
}
}
請注意,不是角色表。
解決步驟2:新增一個查凍結功能的中介軟體 ,並在 Kernel.php 中指定順序
中介軟體名字自定,比如叫 PubUser
Kernel.php
protected $routeMiddleware = [
。。。
'pubuser' => \App\Http\Middleware\PubUser::class,
'jwt.auth' => \Tymon\JWTAuth\Http\Middleware\Authenticate::class,
];
protected $middlewarePriority = [
\Tymon\JWTAuth\Http\Middleware\Authenticate::class,
\App\Http\Middleware\PubUser::class,
];
class PubUser
{
public function handle($request, Closure $next)
{
$user_sub = 角色表::query()->where('user_id', $request->user()->id)
->where('role_type', JWTAuth::getClaim('role_type'))
->firstOrFail();
if ($user_sub->is_valid != 1) {
throw new JWTException('您的賬號被凍結');
}
return $next($request);
}
}
解決步驟3:登陸時,選擇正確的子類
如下程式碼,當選擇了正確的子類時,該子類的自定義資料將會被放到 JWT 的 token 中,然後就可以每次都讀取自定義資料了。
public function success_login($user)
{
// $user 必須是 UserType2 或 UserType1 的例項,決不能是 User 的例項
$new_token = auth()->login($user);
return [
'new_token' => $new_token,
'expire_time' => time() + config('jwt.ttl') * 60,
];
}
解決步驟4:載入帶有檢查凍結功能中介軟體的路由
注意,下面的路由都是必須登陸後才能使用的。
登陸路由另外寫。
api.php
Route::middleware(['jwt.auth', 'pubuser' ])->group(function () {
Route::any('/route1', 'IndexController@route1' );
Route::any('/route2', 'IndexController@route2' );
});
總的來說,就是輕鬆搞定。
媽媽再也不用擔心我不知道怎麼在 JWT 中新增自定義資料了!
本作品採用《CC 協議》,轉載必須註明作者和本文連結