com.addplus.server.action.config.token.TokenService Maven / Gradle / Ivy
The newest version!
package com.addplus.server.action.config.token;
import com.addplus.server.core.constant.CacheConstsBase;
import com.addplus.server.core.constant.ConfigConstsBase;
import com.addplus.server.core.model.base.Token;
import com.addplus.server.core.utils.security.AESUtils;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
/**
* 类名: TokenService
*
* @author zhangjiehang
* @version V1.0
* @date 2018/6/22 上午10:53
* @description 类描述: Token类信息生成
*/
@Service
@Slf4j
public class TokenService {
@Autowired
private RedisTemplate redisTemplate;
@Value("${spring.profiles.active}")
private String actice;
@Value("${action.token.duration:10000}")
private Long duration;
/**
* 方法描述:生成Token码
*
* @param
* @return
* @throws Exception
* @author zhangjiehang
* @date 2018/6/22 上午11:07
*/
public Token getTokenKey(String memberId) {
//删除原有的key
removeTokenKey(memberId);
Token token = new Token();
String secretKey = new ObjectId().toString().substring(8, 24);
token.setAccessKey(new ObjectId().toString());
token.setSecretKey(secretKey);
token.setMemId(memberId);
redisTemplate.opsForValue().set(CacheConstsBase.TOKEN_REDIS_PREFIX + token.getAccessKey(), memberId, 24, TimeUnit.HOURS);
redisTemplate.opsForValue().set(CacheConstsBase.TOKEN_MEMBER_REDIS_PREFIX + memberId, JSON.toJSONString(token), 24, TimeUnit.HOURS);
return token;
}
public Token getTokenKey(String memberId, Long timeStamp) {
//删除原有的key
removeTokenKey(memberId);
Token token = new Token();
String secretKey = new ObjectId().toString().substring(8, 24);
token.setAccessKey(new ObjectId().toString());
token.setSecretKey(secretKey);
// 计算时间戳
long timeDifference = System.currentTimeMillis() - timeStamp;
token.setTimeDifference(timeDifference);
token.setMemId(memberId);
redisTemplate.opsForValue().set(CacheConstsBase.TOKEN_REDIS_PREFIX + token.getAccessKey(), memberId, 24, TimeUnit.HOURS);
redisTemplate.opsForValue().set(CacheConstsBase.TOKEN_MEMBER_REDIS_PREFIX + memberId, JSON.toJSONString(token), 24, TimeUnit.HOURS);
return token;
}
public void removeTokenKey(String memberId) {
if (redisTemplate.hasKey(CacheConstsBase.TOKEN_REDIS_PREFIX + memberId)) {
Object tokenObj = redisTemplate.opsForValue().get(CacheConstsBase.TOKEN_MEMBER_REDIS_PREFIX + memberId);
if (tokenObj != null) {
Token token = JSON.parseObject(tokenObj.toString(), Token.class);
if (token != null) {
redisTemplate.delete(CacheConstsBase.TOKEN_MEMBER_REDIS_PREFIX + memberId);
redisTemplate.delete(CacheConstsBase.TOKEN_REDIS_PREFIX + token.getAccessKey());
}
}
}
}
@Async
public void refreshToken(String accessKey, String memberId) {
boolean isExit = redisTemplate.hasKey(CacheConstsBase.TOKEN_MEMBER_REDIS_PREFIX + memberId);
boolean isExitAccessKey = redisTemplate.hasKey(CacheConstsBase.TOKEN_REDIS_PREFIX + accessKey);
if (isExit && isExitAccessKey) {
boolean isUpdateSuccess = redisTemplate.expire(CacheConstsBase.TOKEN_MEMBER_REDIS_PREFIX + memberId, 2, TimeUnit.DAYS);
boolean isUpdateAccessKeySuccess = redisTemplate.expire(CacheConstsBase.TOKEN_REDIS_PREFIX + accessKey, 2, TimeUnit.DAYS);
if (!isUpdateSuccess || !isUpdateAccessKeySuccess) {
log.error("更新token失败,memberId:" + memberId);
}
}
}
/**
* 方法描述:刷新已经存在的token
*
* @param token 用户传进来的token
* @return Integer 0:成功,1:不存在token,2:非法token,3:请求超时
* @throws Exception
* @author zhangjiehang
* @date 2019/3/15 11:31 AM
*/
public Token checkToken(String token) {
long nowTimeStamp = System.currentTimeMillis();
Token tokenStatus = new Token();
if (StringUtils.isBlank(token)) {
tokenStatus.setStatus(1);
return tokenStatus;
}
if (token.length() <= 24) {
tokenStatus.setStatus(1);
return tokenStatus;
}
int tokenLength = token.length();
String accessKey = token.substring(0, tokenLength - 24);
boolean isExit = redisTemplate.hasKey(CacheConstsBase.TOKEN_REDIS_PREFIX + accessKey);
if (isExit) {
String memberId = (String) redisTemplate.opsForValue().get(CacheConstsBase.TOKEN_REDIS_PREFIX + accessKey);
boolean isExitMember = redisTemplate.hasKey(CacheConstsBase.TOKEN_MEMBER_REDIS_PREFIX + memberId);
if (!isExitMember) {
redisTemplate.delete(CacheConstsBase.TOKEN_REDIS_PREFIX + accessKey);
tokenStatus.setStatus(1);
return tokenStatus;
}
Object secretKeyObj = redisTemplate.opsForValue().get(CacheConstsBase.TOKEN_MEMBER_REDIS_PREFIX + memberId);
if (secretKeyObj == null) {
tokenStatus.setStatus(1);
return tokenStatus;
}
Token tokenOrign = JSON.parseObject(secretKeyObj.toString(), Token.class);
//解密字符是时间戳
String signDecrypt = AESUtils.decryptAES(token.substring(tokenLength - 24, tokenLength), tokenOrign.getSecretKey(), 0);
if (StringUtils.isBlank(signDecrypt)) {
tokenStatus.setStatus(2);
return tokenStatus;
} else {
if (tokenOrign.getTimeDifference() == null) {
tokenOrign.setTimeDifference(0L);
}
//校验当前请求是否还在有效期
long requestTimeStamp = Long.parseLong(signDecrypt);
Long timeDifference = Math.abs(nowTimeStamp - requestTimeStamp - tokenOrign.getTimeDifference());
Long timeNoDifference = Math.abs(nowTimeStamp - requestTimeStamp);
//获取后面校验部分,当前设定10s为有效请求时间
if (this.duration.compareTo(timeNoDifference) != -1 || this.duration.compareTo(timeDifference) != -1) {
this.refreshToken(accessKey, memberId);
tokenStatus.setStatus(0);
tokenStatus.setMemId(tokenOrign.getMemId());
} else {
tokenStatus.setStatus(3);
}
return tokenStatus;
}
} else {
tokenStatus.setStatus(1);
return tokenStatus;
}
}
public Boolean isDevProfiles() {
if ("dev".equals(actice)) {
return true;
}
return false;
}
}