MrShi
2025-03-12 69a1b3bf45738f048361ee4ccb6bdc64fce35720
server/system_service/src/main/java/com/doumee/config/jwt/JwtTokenUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,247 @@
package com.doumee.config.jwt;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.doumee.biz.system.SystemDictDataBiz;
import com.doumee.service.business.third.model.LoginUserInfo;
import com.doumee.core.utils.Constants;
import com.doumee.core.utils.HttpsUtil;
import com.doumee.dao.system.SystemUserMapper;
import com.doumee.dao.system.model.SystemUser;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Component
@Slf4j
public class JwtTokenUtil {
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Resource
    private JwtProperties jwtProperties;
    @Autowired
    private SystemDictDataBiz systemDictDataBiz ;
    @Autowired
    private SystemUserMapper systemUserMapper;
    /**
     * ç”Ÿæˆtoken令牌
     *
     * @param payloads ä»¤ç‰Œä¸­æºå¸¦çš„附加信息
     * @return ä»¤token牌
     */
    public String generateToken( LoginUserInfo payloads) {
        if(payloads == null){
            return  null;
        }
        payloads.setLoginDate(new Date());
        Map<String,Object> map = new HashMap<>();
        map.put("id",payloads.getId());
//        Map<String,Object> map =   BeanUtil.beanToMap(payloads);
        return generateTokenDo(payloads);
    }
    /**
     * ä»Žä»¤ç‰Œä¸­èŽ·å–ç”¨æˆ·å
     *
     * @param token ä»¤ç‰Œ
     * @return ç”¨æˆ·å
     */
    public String getUsernameFromToken(String token) {
        String username;
        try {
            LoginUserInfo claims = getClaimsFromToken(token);
            username = claims.getUsername();
        } catch (Exception e) {
            username = null;
        }
        return username;
    }
    public LoginUserInfo getUserInfoByToken(String token) {
        try {
            LoginUserInfo claims = getClaimsFromToken(token);
            return claims;
        } catch (Exception e) {
           e.printStackTrace();
        }
        return null;
    }
    /**
     * åˆ¤æ–­ä»¤ç‰Œæ˜¯å¦è¿‡æœŸ
     *
     * @param token ä»¤ç‰Œ
     * @return æ˜¯å¦è¿‡æœŸ
     */
    public Boolean isTokenExpired(String token) {
        try {
            LoginUserInfo claims = getClaimsFromToken(token);
            Date expiration = //claims.getLoginDate();
            new Date(claims.getLoginDate().getTime() + jwtProperties.getExpiration());
            return expiration.before(new Date());
        } catch (Exception e) {
            //验证JWT签名失败等同于令牌过期
            return true;
        }
    }
    /**
     * åˆ·æ–°ä»¤ç‰Œ
     *
     * @param token åŽŸä»¤ç‰Œ
     * @return æ–°ä»¤ç‰Œ
     */
    public String refreshToken(String token) {
        String refreshedToken;
        try {
            LoginUserInfo claims = getClaimsFromToken(token);
            claims.setLoginDate(new Date());
            refreshedToken = generateTokenDo(claims);
            if(refreshedToken!=null){
                redisTemplate.delete(Constants.REDIS_TOKEN_KEY+token);//删除老的token
            }
        } catch (Exception e) {
            refreshedToken = null;
        }
        return refreshedToken;
    }
    /**
     * é€€å‡ºç™»é™†
     *
     * @param token åŽŸä»¤ç‰Œ
     * @return æ–°ä»¤ç‰Œ
     */
    public void logout(String token) {
        try {
            //登出海康系统数据
            LoginUserInfo loginUserInfo = this.getUserInfoByToken(token);
            String url = systemDictDataBiz.queryByCode(Constants.HK_PARAM,Constants.HK_HTTPS).getCode() +
                    systemDictDataBiz.queryByCode(Constants.HK_PARAM,Constants.HK_HOST).getCode() +
                    systemDictDataBiz.queryByCode(Constants.HK_PARAM,Constants.LOGIN_OUT_URL).getCode();
            if(StringUtils.isNotBlank(loginUserInfo.getHkMenuToken())){
                log.info("调起海康退出登录=======================>"+url+"?token="+loginUserInfo.getHkMenuToken());
//                this.hkLoginOut(url+"?token="+loginUserInfo.getHkMenuToken());
                HttpsUtil.get(url+"?token="+loginUserInfo.getHkMenuToken(),true);
            }
            //删除老的token
            redisTemplate.delete(Constants.REDIS_TOKEN_KEY+token);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void logoutForH5(String token) {
        try {
            //登出海康系统数据
            LoginUserInfo loginUserInfo = this.getUserInfoByToken(token);
            //删除老的token
            redisTemplate.delete(Constants.REDIS_TOKEN_KEY+token);
            systemUserMapper.update(null,new UpdateWrapper<SystemUser>().lambda().set(SystemUser::getOpenid,null)
                    .eq(SystemUser::getId,loginUserInfo.getId()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void hkLoginOut(String url){
        try {
            // åˆ›å»ºHttpClient对象
            HttpClient httpClient = HttpClientBuilder.create().build();
            // åˆ›å»ºHttpGet对象,指定要访问的URL地址
            HttpGet httpGet = new HttpGet(url);
            // å‘送GET请求,获取响应
            HttpResponse response = httpClient.execute(httpGet);
            // èŽ·å–å“åº”çŠ¶æ€ç 
            int statusCode = response.getStatusLine().getStatusCode();
            // åˆ¤æ–­è¯·æ±‚是否成功
            if (statusCode == 200) {
                // èŽ·å–å“åº”å†…å®¹
                HttpEntity entity = response.getEntity();
                String responseContent = EntityUtils.toString(entity, "UTF-8");
                System.out.println(responseContent);
                log.info("调起海康退出登录返回信息=======================>"+responseContent);
            } else {
                System.out.println("请求失败,响应码:" + statusCode);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * éªŒè¯ä»¤ç‰Œ
     *
     * @param token       ä»¤ç‰Œ
     * @param userId  ç”¨æˆ·Id用户名
     * @return æ˜¯å¦æœ‰æ•ˆ
     */
    public Boolean validateToken(String token, String userId) {
        String username = getUsernameFromToken(token);
        return (username.equals(userId) && !isTokenExpired(token));
    }
    /**
     * ä»Žclaims生成令牌,如果看不懂就看谁调用它
     *
     * @return ä»¤ç‰Œ
     */
    private String generateTokenDo(LoginUserInfo userInfo) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("id",userInfo.getId());
        Date expirationDate = new Date(System.currentTimeMillis() + jwtProperties.getExpiration());
        String token = Jwts.builder().setClaims(claims)
                .setExpiration(expirationDate)
                .signWith(SignatureAlgorithm.HS512, jwtProperties.getSecret())
                .compact();
        redisTemplate.opsForValue().set(Constants.REDIS_TOKEN_KEY+token,JSONObject.toJSONString(userInfo),jwtProperties.getExpiration(), TimeUnit.MILLISECONDS);
        return token;
    }
    /**
     * ä»Žä»¤ç‰Œä¸­èŽ·å–æ•°æ®å£°æ˜Ž,验证JWT签名
     *
     * @param token ä»¤ç‰Œ
     * @return æ•°æ®å£°æ˜Ž
     */
    private LoginUserInfo getClaimsFromToken(String token) {
        LoginUserInfo claims;
        try {
            String userInfo = (String) redisTemplate.opsForValue().get(Constants.REDIS_TOKEN_KEY+token);
            claims = JSONObject.toJavaObject(JSONObject.parseObject(userInfo),LoginUserInfo.class);
        } catch (Exception e) {
            claims = null;
        }
        return claims;
    }
    /**
     * å‘后延伸有效期保持会话继续
     * @param token
     */
    public void refreshTokenTime(String token ) {
        redisTemplate.expire(Constants.REDIS_TOKEN_KEY+token,jwtProperties.getExpiration(), TimeUnit.MILLISECONDS);
//        redisTemplate.opsForValue().set(Constants.REDIS_TOKEN_KEY+token,usrerInfo,jwtProperties.getExpiration(), TimeUnit.MILLISECONDS);
    }
}