zoukankan      html  css  js  c++  java
  • 前端token刷新并发处理

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

    中间件代码

       <?php
       
       namespace AppHttpMiddleware;
       
       use Closure;
       use JWTAuth;
       use TymonJWTAuthExceptionsJWTException;
       use TymonJWTAuthExceptionsTokenExpiredException;
       use TymonJWTAuthExceptionsTokenInvalidException;
       use IlluminateSupportFacadesRedis;
       
       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;
           }
       }
       
  • 相关阅读:
    查看Ubuntu版本
    CentOS下实现postgresql开机自启动
    CentOS下查看crontab执行历史记录
    经常使用的一个python logging封装,支持同时向console和文件输出
    crontab中执行postgresql命令
    postgresql下一种对已有数据进行重新分表的plpgsql脚本
    2012需要分析的一些技术(1)
    Python Extension Packages for Windows
    一个简单的根据行数对大文件进行分片的python程序
    偶拾
  • 原文地址:https://www.cnblogs.com/fenle/p/10666559.html
Copyright © 2011-2022 走看看