package com.propertyManagement.business.service; import cn.hutool.core.util.ObjUtil; import com.propertyManagement.business.domain.vo.LoginWxUser; import com.propertyManagement.common.constant.CacheConstants; import com.propertyManagement.common.constant.Constants; import com.propertyManagement.common.utils.StringUtils; import com.propertyManagement.common.utils.redis.RedisUtils; import com.propertyManagement.common.utils.uuid.IdUtils; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import java.time.Duration; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; /** * token验证处理 * * @author liushuai * @date 2025/05/13 */ @Component public class WxUserTokenService { // 令牌自定义标识 @Value("${sa-token.token-name}") private String header; // 令牌秘钥 @Value("${sa-token.jwt-secret-key}") private String secret; // 一分钟 protected static final long MILLIS_SECOND = 60000; private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L; /** * 获取用户身份信息 * * @return 用户信息 */ public LoginWxUser getWxLogin(HttpServletRequest request) { // 获取请求携带的令牌 String token = getToken(request); if (StringUtils.isNotEmpty(token)) { try { Claims claims = parseToken(token); // 解析对应的权限以及用户信息 String uuid = (String) claims.get(Constants.LOGIN_USER_KEY); String userKey = getTokenKey(uuid); return RedisUtils.getCacheObject(userKey); } catch (Exception ignored) { } } return null; } /** * 设置用户身份信息 */ public void setLoginMember(LoginWxUser wxUser) { if (ObjUtil.isNotEmpty(wxUser) && StringUtils.isNotEmpty(wxUser.getToken())) { refreshToken(wxUser); } } /** * 删除用户身份信息 */ public void delLoginMember(String token) { if (StringUtils.isNotEmpty(token)) { String userKey = getTokenKey(token); RedisUtils.deleteObject(userKey); } } /** * 创建令牌 * * @param wxUser 用户信息 * @return 令牌 */ public String createToken(LoginWxUser wxUser) { String token = IdUtils.fastUUID(); wxUser.setToken(token); refreshToken(wxUser); Map claims = new HashMap<>(); claims.put(Constants.LOGIN_USER_KEY, token); return createToken(claims); } /** * 验证令牌有效期,相差不足20分钟,自动刷新缓存 * * @param loginWxUser 111 * @return 令牌 */ public void verifyToken(LoginWxUser loginWxUser) { long expireTime = loginWxUser.getExpireTime(); long currentTime = System.currentTimeMillis(); if (expireTime - currentTime <= MILLIS_MINUTE_TEN) { refreshToken(loginWxUser); } } /** * 刷新令牌有效期 * * @param wxUser 登录信息 */ public void refreshToken(LoginWxUser wxUser) { wxUser.setLoginTime(System.currentTimeMillis()); wxUser.setExpireTime(wxUser.getLoginTime() + Constants.TOKEN_EXPIRATION * MILLIS_SECOND); // 根据uuid将loginUser缓存 String userKey = getTokenKey(wxUser.getToken()); RedisUtils.setCacheObject(userKey, wxUser, Duration.ofMinutes(Constants.TOKEN_EXPIRATION)); } /** * 从数据声明生成令牌 * * @param claims 数据声明 * @return 令牌 */ private String createToken(Map claims) { return Jwts.builder() .setClaims(claims) .signWith(SignatureAlgorithm.HS512, secret).compact(); } /** * 从令牌中获取数据声明 * * @param token 令牌 * @return 数据声明 */ private Claims parseToken(String token) { return (Claims) Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody(); } /** * 获取请求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 CacheConstants.LOGIN_MERCHANT_TOKEN_KEY + uuid; } }