package ink.wgink.app; import com.alibaba.fastjson.JSONObject; import ink.wgink.app.entity.AppToken; import ink.wgink.app.entity.AppTokenUser; import ink.wgink.app.enums.AppTokenTypeEnum; import ink.wgink.exceptions.TokenException; import ink.wgink.interfaces.consts.ISystemConstant; import ink.wgink.util.AesUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * When you feel like quitting. Think about why you started * 当你想要放弃的时候,想想当初你为何开始 * * @ClassName: AppTokenManager * @Description: AppToken管理 * @Author: WangGeng * @Date: 2019-08-02 11:08 * @Version: 1.0 **/ @Slf4j public class AppTokenManager { private static AppTokenManager appTokenManager = AppTokenManagerBuilder.appTokenManager; private static final Map tokens = new ConcurrentHashMap(); private AppTokenManager() { } public static AppTokenManager getInstance() { return appTokenManager; } /** * 获取token * * @param token * @return */ public AppToken getToken(String token) { AppToken appToken = tokens.get(token); if (appToken != null) { appToken.setLastTime(System.currentTimeMillis()); } return appToken; } /** * 添加token * * @param token * @param appTokenTypeEnum * @param appTokenUser */ public synchronized void addToken(String token, AppTokenTypeEnum appTokenTypeEnum, AppTokenUser appTokenUser) { AppToken appToken = new AppToken(); appToken.setToken(token); appToken.setAppTokenTypeEnum(appTokenTypeEnum); appToken.setLastTime(System.currentTimeMillis()); appToken.setAppTokenUser(appTokenUser); appToken.setUserId(appTokenUser.getId()); for (Map.Entry kvs : tokens.entrySet()) { if (StringUtils.equals(appTokenUser.getId(), kvs.getValue().getUserId())) { tokens.remove(kvs.getValue().getToken()); break; } } tokens.put(token, appToken); } public AppTokenUser parseToAppTokenUser(String token) throws TokenException { String userInfo = null; try { userInfo = AesUtil.aesCommonDecoder(ISystemConstant.APP_TOKEN_AES_KEY, new String(Base64.decodeBase64(token), "UTF-8")); } catch (Exception e) { log.error(e.getMessage(), e); throw new TokenException("Token解码异常"); } JSONObject userInfoObj = JSONObject.parseObject(userInfo); if (userInfoObj == null) { throw new TokenException("Token非法"); } String appTokenSign = userInfoObj.getString(ISystemConstant.APP_TOKEN_SIGN); if (StringUtils.isBlank(appTokenSign)) { log.debug("Token标识为空"); throw new TokenException("Token非法"); } if (!StringUtils.startsWith(appTokenSign, ISystemConstant.APP_TOKEN_VERIFY)) { log.debug("Token标识开头错误"); throw new TokenException("Token非法"); } String[] appTokenSignArray = appTokenSign.split("_"); if (appTokenSignArray.length != 3) { log.debug("Token标识格式长度异常,应为3,这里为:{}", appTokenSignArray.length); throw new TokenException("Token非法"); } try { new Date(Long.parseLong(appTokenSignArray[2])); } catch (NumberFormatException e) { e.printStackTrace(); log.debug("Token时间戳异常"); throw new TokenException("Token非法"); } return JSONObject.toJavaObject(userInfoObj, AppTokenUser.class); } /** * 当前用户列表 * * @return */ public List listCurrentUsers() { List users = new ArrayList<>(); for (Map.Entry kvs : tokens.entrySet()) { AppToken appToken = kvs.getValue(); users.add(appToken.getAppTokenUser()); } return users; } /** * 清空超时Token */ public synchronized void clearTimeoutToken() { long currentTime = System.currentTimeMillis(); List clearTokenKeys = new ArrayList<>(0); for (Map.Entry kvs : tokens.entrySet()) { AppToken appToken = kvs.getValue(); // 超过10分钟 if (currentTime - appToken.getLastTime() > 600000L) { clearTokenKeys.add(kvs.getKey()); } } for (String tokenKey : clearTokenKeys) { tokens.remove(tokenKey); } log.debug("本次共清理超时Token:{}个", clearTokenKeys.size()); } private static class AppTokenManagerBuilder { public static final AppTokenManager appTokenManager = new AppTokenManager(); } }