前端token刷新并发处理

本文介绍了一个PHP中间件,用于处理带有JWT认证的应用程序中的Token刷新逻辑。通过使用Redis缓存来避免并发请求时的Token重复刷新问题。

添加中间件,处理多个前端来的请求时,如果token需要刷新,先查看缓存,如果没有就在redis中做个标志位进行短期缓存,其他的请求发现缓存中的token,就不再刷新token了。这样就避免了重复刷新token的问题。

中间件代码

   <?php
   
   namespace App\Http\Middleware;
   
   use Closure;
   use JWTAuth;
   use Tymon\JWTAuth\Exceptions\JWTException;
   use Tymon\JWTAuth\Exceptions\TokenExpiredException;
   use Tymon\JWTAuth\Exceptions\TokenInvalidException;
   use Illuminate\Support\Facades\Redis;
   
   class GetUserFromToken
   {
       
       public function handle($request, Closure $next)
       {
           $newToken = null;
           $auth = JWTAuth::parseToken();
           if (! $token = $auth->setRequest($request)->getToken()) {
               return response()->json([
                   'code' => '2',
                   'msg' => '无参数token',
                   'data' => '',
               ]);
           }
   
           try {
               $user = $auth->authenticate($token);
               if (! $user) {
                   return response()->json([
                       'code' => '2',
                       'msg' => '未查询到该用户信息',
                       'data' => '',
                    ]);
               }
               $request->headers->set('Authorization','Bearer '.$token);
           } catch (TokenExpiredException $e) {
               try {
                   sleep(rand(1,5)/100);
                   $newToken = JWTAuth::refresh($token);
                   $request->headers->set('Authorization','Bearer '.$newToken); // 给当前的请求设置性的token,以备在本次请求中需要调用用户信息
                   // 将旧token存储在redis中,30秒内再次请求是有效的
                   Redis::setex('token_blacklist:'.$token,30,$newToken);
               } catch (JWTException $e) {
                   // 在黑名单的有效期,放行
                   if($newToken = Redis::get('token_blacklist:'.$token)){
                       $request->headers->set('Authorization','Bearer '.$newToken); // 给当前的请求设置性的token,以备在本次请求中需要调用用户信息
                       return $next($request);
                   }
                   // 过期用户
                   return response()->json([
                       'code' => '2',
                       'msg' => '账号信息过期了,请重新登录',
                   ]);
               }
           } catch (JWTException $e) {
               return response()->json([
                   'code' => '2',
                   'msg' => '无效token',
                   'data' => '',
                ]);
           }
           $response = $next($request);
   
           if ($newToken) {
               $response->headers->set('Authorization', 'Bearer '.$newToken);
           }
   
           return $response;
       }
   }
   

 

转载于:https://www.cnblogs.com/fenle/p/10666559.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值