ruoyi-cloud认证-token改造为双token

ruoyi-cloud认证-token改造为双token

前言

Token在计算机身份认证中是令牌(临时)的意思,在词法分析中是标记的意思。一般作为邀请、登录系统使用。

什么是双token

双token一般是指:access_token和refresh_token。

access_token是一种JWT(json web token),有效时间通常较短,用户在获取资源的时候需要携带access_token,当access_token过期后,如果是活跃用户,就需要使用refresh_token获取一个新的access_token,这样就避免了用户使用正high被踢出去,重新登录,那估计摔手机都有可能。但是对于登录上去,长时间不操作的用户呢,一般会设置超时时间,比如:设置5分钟超时时间,那连续5分钟没有任何操作就会被认为是超时,就会被请下去,需要重新登录,获取新的token。

ruoyi-cloud的token机制简述

  1. 在登录成功后,创建token。
    首先创建UUID,作为userKey,以该key为主键存储用户信息到redis,设置过期时间。
    其次,使用userKey及用户部分信息生成JWT token。而该JWT token即为对客户端暴漏的用户token。
  2. 在业务调用期间,由Gateway的com.ruoyi.gateway.filter.AuthFilter对token的合法性进行校验。上面说到,JWT token中包含userKey信息,则解析JWT token后,即可通过userKey从redis中获取到用户信息。当redis中该信息不存在,则意味着用户token失效。
  3. 那么ruoyi-cloud是怎么对token延期的呢?在com.ruoyi.common.security.interceptor.HeaderInterceptor中可以看到,在每次请求中都调用方法com.ruoyi.common.security.auth.AuthUtil.verifyLoginUserExpire(loginUser),该方法最终执行逻辑如下:
public void verifyToken(LoginUser loginUser)
    {
        long expireTime = loginUser.getExpireTime();
        long currentTime = System.currentTimeMillis();
        if (expireTime - currentTime <= MILLIS_MINUTE_TEN)
        {
            refreshToken(loginUser);
        }
    }

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

即当过期时间减去当前时间小于某一固定时间时,则刷新token。实际是做了token延期处理。

以上,即为ruoyi-cloud的token机制。

存在的问题

  1. 一个token可无限延期下去,过期时间越长,则安全性越低;
  2. token延期的机制,取决于用户请求的时间点、token过期时长、及MILLIS_MINUTE_TEN的取值。比如:token有效时长30分钟,MILLIS_MINUTE_TEN的取值为15分钟,那么在登录后的前15分钟,不会刷新token,即不会延长token。这样就形成了,我在第14分钟还在操作,本身人为要到第44分钟token才会过期,结果在第30分钟token就过期了。(😊有点绕)

如何改造

主要流程见下图:
双token认证机制

主要处理逻辑

  1. 用户登录验证通过,则分别生成accessToken、refreshToken,并将它们对应的过期时间一并返回给客户端;
  2. 客户端存储信息,在每次业务交互时,验证本地的token过期时间;
  3. 如果accessToken未过期,则携带accessToken调用业务接口;
  4. 如果accessToken已过期,refreshToken未过期,则携带refreshToken调用/auth/refresh接口,获取新的accessToken;
  5. 如果accessToken已过期,refreshToken已过期,则跳转要求重新登录。

实现关键代码

登录token创建
public Map<String, Object> createAllToken(LoginUser loginUser)
    {
        String token = IdUtils.fastUUID();
        String refToken = IdUtils.fastUUID();
        Long userId = loginUser.getSysUser().getUserId();
        Long deptId = loginUser.getSysUser().getDeptId();
        String userName = loginUser.getSysUser().getUserName();
        long currentTimeMillis = System.currentTimeMillis();
        long expires_time = currentTimeMillis+ expireTime * MILLIS_MINUTE;
        long refresh_expires_time = currentTimeMillis + refreshExpireTime * MILLIS_MINUTE;
    loginUser<span class="token punctuation">.</span><span class="token function">setUserid</span><span class="token punctuation">(</span>userId<span class="token punctuation">)</span><span class="token punctuation">;</span>
    loginUser<span class="token punctuation">.</span><span class="token function">setUsername</span><span class="token punctuation">(</span>userName<span class="token punctuation">)</span><span class="token punctuation">;</span>
    loginUser<span class="token punctuation">.</span><span class="token function">setDeptId</span><span class="token punctuation">(</span>deptId<span class="token punctuation">)</span><span class="token punctuation">;</span>
    loginUser<span class="token punctuation">.</span><span class="token function">setIpaddr</span><span class="token punctuation">(</span><span class="token class-name">IpUtils</span><span class="token punctuation">.</span><span class="token function">getIpAddr</span><span class="token punctuation">(</span><span class="token class-name">ServletUtils</span><span class="token punctuation">.</span><span class="token function">getRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    loginUser<span class="token punctuation">.</span><span class="token function">setLoginTime</span><span class="token punctuation">(</span><span class="token class-name">System</span><span class="token punctuation">.</span><span class="token function">currentTimeMillis</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    loginUser<span class="token punctuation">.</span><span class="token function">setToken</span><span class="token punctuation">(</span>token<span class="token punctuation">)</span><span class="token punctuation">;</span>
    loginUser<span class="token punctuation">.</span><span class="token function">setRefToken</span><span class="token punctuation">(</span>refToken<span class="token punctuation">)</span><span class="token punctuation">;</span>
    loginUser<span class="token punctuation">.</span><span class="token function">setExpireTime</span><span class="token punctuation">(</span>expires_time<span class="token punctuation">)</span><span class="token punctuation">;</span>
    loginUser<span class="token punctuation">.</span><span class="token function">setRefExpireTime</span><span class="token punctuation">(</span>refresh_expires_time<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token function">cacheAllToken</span><span class="token punctuation">(</span>loginUser<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// Jwt存储信息</span>
    <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> claimsMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    claimsMap<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token class-name">SecurityConstants</span><span class="token punctuation">.</span>USER_KEY<span class="token punctuation">,</span> token<span class="token punctuation">)</span><span class="token punctuation">;</span>
    claimsMap<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token class-name">SecurityConstants</span><span class="token punctuation">.</span>DETAILS_USER_ID<span class="token punctuation">,</span> userId<span class="token punctuation">)</span><span class="token punctuation">;</span>
    claimsMap<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token class-name">SecurityConstants</span><span class="token punctuation">.</span>DETAILS_DEPT_ID<span class="token punctuation">,</span> deptId<span class="token punctuation">)</span><span class="token punctuation">;</span>
    claimsMap<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token class-name">SecurityConstants</span><span class="token punctuation">.</span>DETAILS_USERNAME<span class="token punctuation">,</span> userName<span class="token punctuation">)</span><span class="token punctuation">;</span>
    claimsMap<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token class-name">SecurityConstants</span><span class="token punctuation">.</span>TOKEN_TYPE<span class="token punctuation">,</span> <span class="token class-name">SecurityConstants</span><span class="token punctuation">.</span>TOKEN_TYPE_ACCESS<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token class-name">String</span> accToken <span class="token operator">=</span> <span class="token class-name">JwtUtils</span><span class="token punctuation">.</span><span class="token function">createToken</span><span class="token punctuation">(</span>claimsMap<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// Jwt ref token</span>
    claimsMap<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token class-name">SecurityConstants</span><span class="token punctuation">.</span>USER_KEY<span class="token punctuation">,</span> refToken<span class="token punctuation">)</span><span class="token punctuation">;</span>
    claimsMap<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token class-name">SecurityConstants</span><span class="token punctuation">.</span>TOKEN_TYPE<span class="token punctuation">,</span> <span class="token class-name">SecurityConstants</span><span class="token punctuation">.</span>TOKEN_TYPE_REFRESH<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token class-name">String</span> refreshToken <span class="token operator">=</span> <span class="token class-name">JwtUtils</span><span class="token punctuation">.</span><span class="token function">createToken</span><span class="token punctuation">(</span>claimsMap<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 接口返回信息</span>
    <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> rspMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    rspMap<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"access_token"</span><span class="token punctuation">,</span> accToken<span class="token punctuation">)</span><span class="token punctuation">;</span>
    rspMap<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"expires_in"</span><span class="token punctuation">,</span> expireTime<span class="token punctuation">)</span><span class="token punctuation">;</span>
    rspMap<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"expires_time"</span><span class="token punctuation">,</span> expires_time<span class="token punctuation">)</span><span class="token punctuation">;</span>
    rspMap<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"refresh_token"</span><span class="token punctuation">,</span> refreshToken<span class="token punctuation">)</span><span class="token punctuation">;</span>
    rspMap<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"refresh_expires_in"</span><span class="token punctuation">,</span> refreshExpireTime<span class="token punctuation">)</span><span class="token punctuation">;</span>
    rspMap<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"refresh_expires_time"</span><span class="token punctuation">,</span> refresh_expires_time<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">return</span> rspMap<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

可以看到,创建两个token,并返回。且两个token的信息中,仅userKey、过期时间不一致,其余信息都一致。两个token都作为userKey,存储用户信息到redis。refreshToken的过期时间长与accessToken的过期时间。

token刷新

根据refreshToken获取到用户信息

String userkey = JwtUtils.getUserKey(refreshToken);
return redisService.getCacheObject(getRefTokenKey(userkey));

 
 
  • 1
  • 2

从refreshToken中解析出userKey,然后取出登录用户信息。

创建accessToken,并建立新的accessToken与refreshToken的映射关系

public Map<String, Object> createAccessToken(LoginUser loginUser)
    {
        // 在创建新的accessToken前,判断之前的token是否存在,如果存在则删除
        String oldToken = loginUser.getToken();
        delAccessToken(oldToken);
        String token = IdUtils.fastUUID();
        long currentTimeMillis = System.currentTimeMillis();
        long expires_time = currentTimeMillis+ expireTime * MILLIS_MINUTE;
    loginUser<span class="token punctuation">.</span><span class="token function">setIpaddr</span><span class="token punctuation">(</span><span class="token class-name">IpUtils</span><span class="token punctuation">.</span><span class="token function">getIpAddr</span><span class="token punctuation">(</span><span class="token class-name">ServletUtils</span><span class="token punctuation">.</span><span class="token function">getRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    loginUser<span class="token punctuation">.</span><span class="token function">setLoginTime</span><span class="token punctuation">(</span><span class="token class-name">System</span><span class="token punctuation">.</span><span class="token function">currentTimeMillis</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    loginUser<span class="token punctuation">.</span><span class="token function">setToken</span><span class="token punctuation">(</span>token<span class="token punctuation">)</span><span class="token punctuation">;</span>
    loginUser<span class="token punctuation">.</span><span class="token function">setExpireTime</span><span class="token punctuation">(</span>expires_time<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token function">cacheAccessToken</span><span class="token punctuation">(</span>loginUser<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// Jwt存储信息</span>
    <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> claimsMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    claimsMap<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token class-name">SecurityConstants</span><span class="token punctuation">.</span>USER_KEY<span class="token punctuation">,</span> token<span class="token punctuation">)</span><span class="token punctuation">;</span>
    claimsMap<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token class-name">SecurityConstants</span><span class="token punctuation">.</span>DETAILS_USER_ID<span class="token punctuation">,</span> loginUser<span class="token punctuation">.</span><span class="token function">getUserid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    claimsMap<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token class-name">SecurityConstants</span><span class="token punctuation">.</span>DETAILS_DEPT_ID<span class="token punctuation">,</span> loginUser<span class="token punctuation">.</span><span class="token function">getDeptId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    claimsMap<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token class-name">SecurityConstants</span><span class="token punctuation">.</span>DETAILS_USERNAME<span class="token punctuation">,</span> loginUser<span class="token punctuation">.</span><span class="token function">getUsername</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    claimsMap<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token class-name">SecurityConstants</span><span class="token punctuation">.</span>TOKEN_TYPE<span class="token punctuation">,</span> <span class="token class-name">SecurityConstants</span><span class="token punctuation">.</span>TOKEN_TYPE_ACCESS<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token class-name">String</span> accToken <span class="token operator">=</span> <span class="token class-name">JwtUtils</span><span class="token punctuation">.</span><span class="token function">createToken</span><span class="token punctuation">(</span>claimsMap<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 接口返回信息</span>
    <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> rspMap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    rspMap<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"access_token"</span><span class="token punctuation">,</span> accToken<span class="token punctuation">)</span><span class="token punctuation">;</span>
    rspMap<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"expires_in"</span><span class="token punctuation">,</span> expireTime<span class="token punctuation">)</span><span class="token punctuation">;</span>
    rspMap<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"expires_time"</span><span class="token punctuation">,</span> expires_time<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> rspMap<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

token的刷新,实际我这里仅创建了新的accessToken,这里就要求将refreshToken的超时时间设置的足够长。这个需要根据业务实际需要综合考虑。实际也可以通过延长refreshToken的过期时间解决。

token的验证
    private static final String REFRESH_PATH = "/auth/refresh";
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpRequest.Builder mutate = request.mutate();
    <span class="token class-name">String</span> url <span class="token operator">=</span> request<span class="token punctuation">.</span><span class="token function">getURI</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getPath</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 跳过不需要验证的路径</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name">StringUtils</span><span class="token punctuation">.</span><span class="token function">matches</span><span class="token punctuation">(</span>url<span class="token punctuation">,</span> ignoreWhite<span class="token punctuation">.</span><span class="token function">getWhites</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">return</span> chain<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span>exchange<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token class-name">String</span> token <span class="token operator">=</span> <span class="token function">getToken</span><span class="token punctuation">(</span>request<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name">StringUtils</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span>token<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">return</span> <span class="token function">unauthorizedResponse</span><span class="token punctuation">(</span>exchange<span class="token punctuation">,</span> <span class="token string">"令牌不能为空"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token class-name">Claims</span> claims <span class="token operator">=</span> <span class="token class-name">JwtUtils</span><span class="token punctuation">.</span><span class="token function">parseToken</span><span class="token punctuation">(</span>token<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>claims <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">return</span> <span class="token function">unauthorizedResponse</span><span class="token punctuation">(</span>exchange<span class="token punctuation">,</span> <span class="token string">"令牌已过期或验证不正确!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token class-name">String</span> userkey <span class="token operator">=</span> <span class="token class-name">JwtUtils</span><span class="token punctuation">.</span><span class="token function">getUserKey</span><span class="token punctuation">(</span>claims<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token class-name">String</span> tokenType <span class="token operator">=</span> <span class="token class-name">JwtUtils</span><span class="token punctuation">.</span><span class="token function">getTokenType</span><span class="token punctuation">(</span>claims<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">boolean</span> isLogin<span class="token punctuation">;</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token class-name">SecurityConstants</span><span class="token punctuation">.</span>TOKEN_TYPE_ACCESS<span class="token punctuation">.</span><span class="token function">equalsIgnoreCase</span><span class="token punctuation">(</span>tokenType<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
        isLogin <span class="token operator">=</span> redisService<span class="token punctuation">.</span><span class="token function">hasKey</span><span class="token punctuation">(</span><span class="token function">getTokenKey</span><span class="token punctuation">(</span>userkey<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token keyword">else</span><span class="token punctuation">{<!-- --></span>
        <span class="token comment">// 如果时refreshToken,则url只能是刷新接口。</span>
        <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span>REFRESH_PATH<span class="token punctuation">.</span><span class="token function">equalsIgnoreCase</span><span class="token punctuation">(</span>url<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
            <span class="token keyword">return</span> <span class="token function">unauthorizedResponse</span><span class="token punctuation">(</span>exchange<span class="token punctuation">,</span> <span class="token string">"令牌验证失败"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        isLogin <span class="token operator">=</span> redisService<span class="token punctuation">.</span><span class="token function">hasKey</span><span class="token punctuation">(</span><span class="token function">getRefTokenKey</span><span class="token punctuation">(</span>userkey<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>isLogin<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">return</span> <span class="token function">accUnauthorizedResponse</span><span class="token punctuation">(</span>exchange<span class="token punctuation">,</span> <span class="token string">"登录状态已过期"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token class-name">String</span> userid <span class="token operator">=</span> <span class="token class-name">JwtUtils</span><span class="token punctuation">.</span><span class="token function">getUserId</span><span class="token punctuation">(</span>claims<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token class-name">String</span> username <span class="token operator">=</span> <span class="token class-name">JwtUtils</span><span class="token punctuation">.</span><span class="token function">getUserName</span><span class="token punctuation">(</span>claims<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token class-name">String</span> deptId <span class="token operator">=</span> <span class="token class-name">JwtUtils</span><span class="token punctuation">.</span><span class="token function">getDeptId</span><span class="token punctuation">(</span>claims<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name">StringUtils</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span>userid<span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token class-name">StringUtils</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span>username<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">return</span> <span class="token function">unauthorizedResponse</span><span class="token punctuation">(</span>exchange<span class="token punctuation">,</span> <span class="token string">"令牌验证失败"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">// 设置用户信息到请求</span>
    <span class="token function">addHeader</span><span class="token punctuation">(</span>mutate<span class="token punctuation">,</span> <span class="token class-name">SecurityConstants</span><span class="token punctuation">.</span>USER_KEY<span class="token punctuation">,</span> userkey<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">addHeader</span><span class="token punctuation">(</span>mutate<span class="token punctuation">,</span> <span class="token class-name">SecurityConstants</span><span class="token punctuation">.</span>DETAILS_USER_ID<span class="token punctuation">,</span> userid<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">addHeader</span><span class="token punctuation">(</span>mutate<span class="token punctuation">,</span> <span class="token class-name">SecurityConstants</span><span class="token punctuation">.</span>DETAILS_DEPT_ID<span class="token punctuation">,</span> deptId<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">addHeader</span><span class="token punctuation">(</span>mutate<span class="token punctuation">,</span> <span class="token class-name">SecurityConstants</span><span class="token punctuation">.</span>DETAILS_USERNAME<span class="token punctuation">,</span> username<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 内部请求来源参数清除</span>
    <span class="token function">removeHeader</span><span class="token punctuation">(</span>mutate<span class="token punctuation">,</span> <span class="token class-name">SecurityConstants</span><span class="token punctuation">.</span>FROM_SOURCE<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> chain<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span>exchange<span class="token punctuation">.</span><span class="token function">mutate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">request</span><span class="token punctuation">(</span>mutate<span class="token punctuation">.</span><span class="token function">build</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">build</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

这里为了严格控制,实际对accessToken、refreshToken增加了tokenType字段。限定refreshToken只能在访问/auth/refresh接口时访问。

以上步骤即完成了双token的改造。

最后

至于为什么改造为双token,以及双token有哪些好处?我在这里就不一一阐述了。
大家有兴趣可以看下这篇文章:http://www.mobiletrain.org/about/BBS/77900.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值