TokenServiceImpl.java 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. package com.ruoyi.system.service.impl;
  2. import cn.hutool.core.util.IdUtil;
  3. import cn.hutool.http.useragent.UserAgent;
  4. import cn.hutool.http.useragent.UserAgentUtil;
  5. import cn.hutool.json.JSONObject;
  6. import cn.hutool.jwt.JWTUtil;
  7. import cn.hutool.jwt.signers.JWTSigner;
  8. import cn.hutool.jwt.signers.JWTSignerUtil;
  9. import com.ruoyi.common.constant.Constants;
  10. import com.ruoyi.common.core.domain.model.LoginUser;
  11. import com.ruoyi.common.core.service.TokenService;
  12. import com.ruoyi.common.properties.TokenProperties;
  13. import com.ruoyi.common.utils.RedisUtils;
  14. import com.ruoyi.common.utils.ServletUtils;
  15. import com.ruoyi.common.utils.StringUtils;
  16. import com.ruoyi.common.utils.ip.AddressUtils;
  17. import org.springframework.beans.factory.annotation.Autowired;
  18. import org.springframework.stereotype.Service;
  19. import javax.servlet.http.HttpServletRequest;
  20. import java.util.HashMap;
  21. import java.util.Map;
  22. import java.util.concurrent.TimeUnit;
  23. /**
  24. * token验证处理
  25. *
  26. * @author Lion Li
  27. */
  28. @Service
  29. public class TokenServiceImpl implements TokenService {
  30. protected static final long MILLIS_SECOND = 1000;
  31. protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
  32. private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L;
  33. @Autowired
  34. private TokenProperties tokenProperties;
  35. /**
  36. * 获取用户身份信息
  37. *
  38. * @return 用户信息
  39. */
  40. @Override
  41. public LoginUser getLoginUser(HttpServletRequest request) {
  42. // 获取请求携带的令牌
  43. String token = getToken(request);
  44. if (StringUtils.isNotEmpty(token)) {
  45. try {
  46. JSONObject claims = parseToken(token);
  47. // 解析对应的权限以及用户信息
  48. String uuid = claims.getStr(Constants.LOGIN_USER_KEY);
  49. String userKey = getTokenKey(uuid);
  50. LoginUser user = RedisUtils.getCacheObject(userKey);
  51. return user;
  52. } catch (Exception e) {
  53. }
  54. }
  55. return null;
  56. }
  57. /**
  58. * 设置用户身份信息
  59. */
  60. @Override
  61. public void setLoginUser(LoginUser loginUser) {
  62. if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) {
  63. refreshToken(loginUser);
  64. }
  65. }
  66. /**
  67. * 删除用户身份信息
  68. */
  69. @Override
  70. public void delLoginUser(String token) {
  71. if (StringUtils.isNotEmpty(token)) {
  72. String userKey = getTokenKey(token);
  73. RedisUtils.deleteObject(userKey);
  74. }
  75. }
  76. /**
  77. * 创建令牌
  78. *
  79. * @param loginUser 用户信息
  80. * @return 令牌
  81. */
  82. @Override
  83. public String createToken(LoginUser loginUser) {
  84. String token = IdUtil.fastUUID();
  85. loginUser.setToken(token);
  86. setUserAgent(loginUser);
  87. refreshToken(loginUser);
  88. Map<String, Object> claims = new HashMap<>();
  89. claims.put(Constants.LOGIN_USER_KEY, token);
  90. return createToken(claims);
  91. }
  92. /**
  93. * 验证令牌有效期,相差不足20分钟,自动刷新缓存
  94. *
  95. * @param loginUser
  96. * @return 令牌
  97. */
  98. @Override
  99. public void verifyToken(LoginUser loginUser) {
  100. long expireTime = loginUser.getExpireTime();
  101. long currentTime = System.currentTimeMillis();
  102. if (expireTime - currentTime <= MILLIS_MINUTE_TEN) {
  103. refreshToken(loginUser);
  104. }
  105. }
  106. /**
  107. * 刷新令牌有效期
  108. *
  109. * @param loginUser 登录信息
  110. */
  111. @Override
  112. public void refreshToken(LoginUser loginUser) {
  113. loginUser.setLoginTime(System.currentTimeMillis());
  114. loginUser.setExpireTime(loginUser.getLoginTime() + tokenProperties.getExpireTime() * MILLIS_MINUTE);
  115. // 根据uuid将loginUser缓存
  116. String userKey = getTokenKey(loginUser.getToken());
  117. RedisUtils.setCacheObject(userKey, loginUser, tokenProperties.getExpireTime(), TimeUnit.MINUTES);
  118. }
  119. /**
  120. * 设置用户代理信息
  121. *
  122. * @param loginUser 登录信息
  123. */
  124. @Override
  125. public void setUserAgent(LoginUser loginUser) {
  126. UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"));
  127. String ip = ServletUtils.getClientIP();
  128. loginUser.setIpaddr(ip);
  129. loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
  130. loginUser.setBrowser(userAgent.getBrowser().getName());
  131. loginUser.setOs(userAgent.getOs().getName());
  132. }
  133. /**
  134. * 从数据声明生成令牌
  135. *
  136. * @param claims 数据声明
  137. * @return 令牌
  138. */
  139. private String createToken(Map<String, Object> claims) {
  140. JWTSigner signer = JWTSignerUtil.hs512(tokenProperties.getSecret().getBytes());
  141. String token = JWTUtil.createToken(claims, signer);
  142. return token;
  143. }
  144. /**
  145. * 从令牌中获取数据声明
  146. *
  147. * @param token 令牌
  148. * @return 数据声明
  149. */
  150. private JSONObject parseToken(String token) {
  151. JWTSigner signer = JWTSignerUtil.hs512(tokenProperties.getSecret().getBytes());
  152. return JWTUtil.parseToken(token).setSigner(signer).getPayload().getClaimsJson();
  153. }
  154. /**
  155. * 从令牌中获取用户名
  156. *
  157. * @param token 令牌
  158. * @return 用户名
  159. */
  160. @Override
  161. public String getUsernameFromToken(String token) {
  162. JSONObject claims = parseToken(token);
  163. return claims.getStr("sub");
  164. }
  165. /**
  166. * 获取请求token
  167. *
  168. * @param request
  169. * @return token
  170. */
  171. private String getToken(HttpServletRequest request) {
  172. String token = request.getHeader(tokenProperties.getHeader());
  173. if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)) {
  174. token = token.replace(Constants.TOKEN_PREFIX, "");
  175. }
  176. return token;
  177. }
  178. private String getTokenKey(String uuid) {
  179. return Constants.LOGIN_TOKEN_KEY + uuid;
  180. }
  181. }