JWT認証ツールクラスパッケージ(メモ)


概要
主にJWT方式のtoken生成に対して、token有効期間内にリフレッシュし、キャッシュ(redisキャッシュ)と組み合わせて、頻繁にデータベースをクエリーしてユーザー情報を取得することを避け、アクセス速度を高める.JWT token+redisキャッシュ方式を採用することで、クラスタ配置下で認証情報が失われること(例えばcookie+session)を効果的に回避し、tokenをリクエストヘッダヘッダに配置すればよい.
Tokenサービスクラスコード
まずJWT依存を導入する必要がある
 
		
			io.jsonwebtoken
			jjwt
			${jwt.version}
		
/**
 * token    
 * 
 * @author ruoyi
 */
@Component
public class TokenService
{
    //        
    @Value("${token.header}")
    private String header;

    //     
    @Value("${token.secret}")
    private String secret;

    //      (  30  )
    @Value("${token.expireTime}")
    private int expireTime;

    protected static final long MILLIS_SECOND = 1000;

    protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;

    private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L;

    @Autowired
    private RedisCache redisCache;

    /**
     *         
     * 
     * @return     
     */
    public LoginUser getLoginUser(HttpServletRequest request)
    {
        //          
        String token = getToken(request);
        if (StringUtils.isNotEmpty(token))
        {
            Claims claims = parseToken(token);
            //              
            String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
            String userKey = getTokenKey(uuid);
            LoginUser user = redisCache.getCacheObject(userKey);
            return user;
        }
        return null;
    }

    /**
     *         
     */
    public void setLoginUser(LoginUser loginUser)
    {
        if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken()))
        {
            refreshToken(loginUser);
        }
    }

    /**
     *         
     */
    public void delLoginUser(String token)
    {
        if (StringUtils.isNotEmpty(token))
        {
            String userKey = getTokenKey(token);
            redisCache.deleteObject(userKey);
        }
    }

    /**
     *     
     * 
     * @param loginUser     
     * @return   
     */
    public String createToken(LoginUser loginUser)
    {
        String token = IdUtils.fastUUID();
        loginUser.setToken(token);
        setUserAgent(loginUser);
        refreshToken(loginUser);

        Map claims = new HashMap<>();
        claims.put(Constants.LOGIN_USER_KEY, token);
        return createToken(claims);
    }

    /**
     *        ,    20  ,      
     * 
     * @param loginUser   
     * @return   
     */
    public void verifyToken(LoginUser loginUser)
    {
        long expireTime = loginUser.getExpireTime();
        long currentTime = System.currentTimeMillis();
        if (expireTime - currentTime <= MILLIS_MINUTE_TEN)
        {
            refreshToken(loginUser);
        }
    }

    /**
     *        
     * 
     * @param loginUser     
     */
    public void refreshToken(LoginUser loginUser)
    {
        loginUser.setLoginTime(System.currentTimeMillis());
        loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
        //   uuid loginUser  
        String userKey = getTokenKey(loginUser.getToken());
        redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
    }
    
    /**
     *         
     * 
     * @param loginUser     
     */
    public void setUserAgent(LoginUser loginUser)
    {
        UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
        String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
        loginUser.setIpaddr(ip);
        loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
        loginUser.setBrowser(userAgent.getBrowser().getName());
        loginUser.setOs(userAgent.getOperatingSystem().getName());
    }
    
    /**
     *          
     *
     * @param claims     
     * @return   
     */
    private String createToken(Map claims)
    {
        String token = Jwts.builder()
                .setClaims(claims)
                .signWith(SignatureAlgorithm.HS512, secret).compact();
        return token;
    }

    /**
     *           
     *
     * @param token   
     * @return     
     */
    private Claims parseToken(String token)
    {
        return Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();
    }

    /**
     *          
     *
     * @param token   
     * @return    
     */
    public String getUsernameFromToken(String token)
    {
        Claims claims = parseToken(token);
        return claims.getSubject();
    }

    /**
     *     token
     *
     * @param request
     * @return token
     */
    private String getToken(HttpServletRequest request)
    {
        String token = request.getHeader(header);
        if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX))
        {
            token = token.replace(Constants.TOKEN_PREFIX, "");
        }
        return token;
    }

    private String getTokenKey(String uuid)
    {
        return Constants.LOGIN_TOKEN_KEY + uuid;
    }
}

redisキャッシュツールクラスパッケージ
/**
 * spring redis    
 * 
 * @author ruoyi
 **/
@SuppressWarnings(value = { "unchecked", "rawtypes" })
@Component
public class RedisCache
{
    @Autowired
    public RedisTemplate redisTemplate;

    /**
     *        ,Integer、String、    
     *
     * @param key      
     * @param value     
     * @return      
     */
    public  ValueOperations setCacheObject(String key, T value)
    {
        ValueOperations operation = redisTemplate.opsForValue();
        operation.set(key, value);
        return operation;
    }

    /**
     *        ,Integer、String、    
     *
     * @param key      
     * @param value     
     * @param timeout   
     * @param timeUnit      
     * @return      
     */
    public  ValueOperations setCacheObject(String key, T value, Integer timeout, TimeUnit timeUnit)
    {
        ValueOperations operation = redisTemplate.opsForValue();
        operation.set(key, value, timeout, timeUnit);
        return operation;
    }

    /**
     *          。
     *
     * @param key     
     * @return          
     */
    public  T getCacheObject(String key)
    {
        ValueOperations operation = redisTemplate.opsForValue();
        return operation.get(key);
    }

    /**
     *       
     *
     * @param key
     */
    public void deleteObject(String key)
    {
        redisTemplate.delete(key);
    }

    /**
     *       
     *
     * @param collection
     */
    public void deleteObject(Collection collection)
    {
        redisTemplate.delete(collection);
    }

    /**
     *   List  
     *
     * @param key      
     * @param dataList     List  
     * @return      
     */
    public  ListOperations setCacheList(String key, List dataList)
    {
        ListOperations listOperation = redisTemplate.opsForList();
        if (null != dataList)
        {
            int size = dataList.size();
            for (int i = 0; i < size; i++)
            {
                listOperation.leftPush(key, dataList.get(i));
            }
        }
        return listOperation;
    }

    /**
     *      list  
     *
     * @param key      
     * @return          
     */
    public  List getCacheList(String key)
    {
        List dataList = new ArrayList();
        ListOperations listOperation = redisTemplate.opsForList();
        Long size = listOperation.size(key);

        for (int i = 0; i < size; i++)
        {
            dataList.add(listOperation.index(key, i));
        }
        return dataList;
    }

    /**
     *   Set
     *
     * @param key     
     * @param dataSet      
     * @return        
     */
    public  BoundSetOperations setCacheSet(String key, Set dataSet)
    {
        BoundSetOperations setOperation = redisTemplate.boundSetOps(key);
        Iterator it = dataSet.iterator();
        while (it.hasNext())
        {
            setOperation.add(it.next());
        }
        return setOperation;
    }

    /**
     *      set
     *
     * @param key
     * @return
     */
    public  Set getCacheSet(String key)
    {
        Set dataSet = new HashSet();
        BoundSetOperations operation = redisTemplate.boundSetOps(key);
        dataSet = operation.members();
        return dataSet;
    }

    /**
     *   Map
     *
     * @param key
     * @param dataMap
     * @return
     */
    public  HashOperations setCacheMap(String key, Map dataMap)
    {
        HashOperations hashOperations = redisTemplate.opsForHash();
        if (null != dataMap)
        {
            for (Map.Entry entry : dataMap.entrySet())
            {
                hashOperations.put(key, entry.getKey(), entry.getValue());
            }
        }
        return hashOperations;
    }

    /**
     *      Map
     *
     * @param key
     * @return
     */
    public  Map getCacheMap(String key)
    {
        Map map = redisTemplate.opsForHash().entries(key);
        return map;
    }

    /**
     *            
     * 
     * @param pattern      
     * @return     
     */
    public Collection keys(String pattern)
    {
        return redisTemplate.keys(pattern);
    }
}