使用 JWT 时,添加自定义数据并在登陆时校验 
                                                    
                        
                    
                    
  
                    
                    使用 JWT 时,添加自定义数据并在登陆时校验
需求如下
同一个用户有两种角色,分别定义了是否可以禁止登陆即冻结。
应用登陆时,需要选择角色,然后才点击登陆按钮。
当后台设置该用户的某个角色冻结时,需要禁止该角色使用我们的应用程序。
解决思路
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 协议》,转载必须注明作者和本文链接
 
           yyy123456 的个人博客
 yyy123456 的个人博客
         
                     
                     
             
           
           关于 LearnKu
                关于 LearnKu
               
                     
                     
                     粤公网安备 44030502004330号
 粤公网安备 44030502004330号 
 
推荐文章: