jiangping
2025-04-07 1c83c89faa55eaae83e362b92159460059ede96e
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
package com.doumee.config.Jwt;
 
import com.alibaba.fastjson.JSONObject;
import com.doumee.biz.system.SystemDictDataBiz;
import com.doumee.core.constants.Constants;
import com.doumee.dao.business.model.Member;
import com.doumee.dao.system.SystemUserMapper;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
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.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
 
@Component
@Slf4j
public class JwtTokenUtil {
 
    public static final String HEADER_KEY = "web_token";
//    @Autowired
//    private RedisTemplate<String,Object> redisTemplate;
 
    @Resource(name="sessionRedisTemplate")
    private RedisTemplate<Object, Serializable> redisTemplate;
    @Resource
    private JwtProperties jwtProperties;
 
    /**
     * 生成token令牌
     *
     * @param payloads 令牌中携带的附加信息
     * @return 令token牌
     */
    public String generateToken( Member payloads) {
        if(payloads == null){
            return  null;
        }
        payloads.setLastLoginDate(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 {
            Member claims = getClaimsFromToken(token);
            username = claims.getQwId();
        } catch (Exception e) {
            username = null;
        }
        return username;
    }
    public Member getUserInfoByToken(String token) {
        try {
            Member claims = getClaimsFromToken(token);
            return claims;
        } catch (Exception e) {
           e.printStackTrace();
        }
        return null;
    }
 
    /**
     * 判断令牌是否过期
     *
     * @param token 令牌
     * @return 是否过期
     */
    public Boolean isTokenExpired(String token) {
        try {
            Member claims = getClaimsFromToken(token);
            Date expiration = //claims.getLoginDate();
            new Date(claims.getLastLoginDate().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 {
            Member claims = getClaimsFromToken(token);
            claims.setLastLoginDate(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       令牌
     * @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(Member 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 Member getClaimsFromToken(String token) {
        Member claims;
        try {
            String userInfo = (String) redisTemplate.opsForValue().get(Constants.REDIS_TOKEN_KEY+token);
            claims = JSONObject.toJavaObject(JSONObject.parseObject(userInfo),Member.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);
    }
}