JWT認証ツールクラスパッケージ(メモ)
概要
主にJWT方式のtoken生成に対して、token有効期間内にリフレッシュし、キャッシュ(redisキャッシュ)と組み合わせて、頻繁にデータベースをクエリーしてユーザー情報を取得することを避け、アクセス速度を高める.JWT token+redisキャッシュ方式を採用することで、クラスタ配置下で認証情報が失われること(例えばcookie+session)を効果的に回避し、tokenをリクエストヘッダヘッダに配置すればよい.
Tokenサービスクラスコード
まずJWT依存を導入する必要がある
redisキャッシュツールクラスパッケージ
主に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);
}
}