doum
2025-09-28 9ab109b9ee96e7ff2bf2b935a044aee5842a3ddc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
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);
            refreshTokenTime(token);
        } catch (Exception e) {
            claims = null;
        }
        return claims;
    }
 
    /**
     * 向后延伸有效期保持会话继续
     * @param token
     */
    public void refreshTokenTime(String token ) {
        log.error("===============开始刷新登录token"+token);
        redisTemplate.expire(Constants.REDIS_TOKEN_KEY+token,jwtProperties.getExpiration(), TimeUnit.MILLISECONDS);
        log.error("===============结束刷新登录token"+token);
//        redisTemplate.opsForValue().set(Constants.REDIS_TOKEN_KEY+token,usrerInfo,jwtProperties.getExpiration(), TimeUnit.MILLISECONDS);
    }
}