测试用户
2023-04-13 43393f2bb11cbf9e6af40077bbc5284660e8a754
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
package com.common.core.utils;
 
import com.common.core.constant.GlobalConst;
import com.common.redis.util.RedisUtil;
import com.common.security.configure.AppDetails;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
 
 
/**
 * @author 廖振钦
 * @date 2022-01-17
 */
@Slf4j
@Component
public class JwtTokenUtil {
    @Autowired
    private RedisUtil redisUtil;
    public static final String CLAIM_KEY_APPID = "appid";
    public static final String CLAIM_KEY_USERID = "userid";
    private static final String CLAIM_KEY_CREATED = "created";
    private Long expiration = GlobalConst.TOKEN_EXPIRE+GlobalConst.TOKEN_EXPIRE_BUFF;
 
    /**
     * 根据负责生成JWT的token
     */
    private String generateToken(Map<String, Object> claims) {
        return Jwts.builder()
                .setClaims(claims)
                .setExpiration(generateExpirationDate())
                .signWith(SignatureAlgorithm.HS512, SM4Utils.getPassword())
                .compact();
    }
 
    /**
     * 从token中获取JWT中的负载
     */
    private Claims getClaimsFromToken(String token) {
        Claims claims = Jwts.parser()
                    .setSigningKey(SM4Utils.getPassword())
                    .parseClaimsJws(token)
                    .getBody();
        return claims;
    }
 
    /**
     * 生成token的过期时间
     */
    private Date generateExpirationDate() {
        return new Date(System.currentTimeMillis() + expiration * 1000);
    }
 
    /**
     * 从token中获取登录用户名
     */
    public String getAppidFromToken(String token) {
        String appid;
        try {
            Claims claims = getClaimsFromToken(token);
            appid = claims.get(CLAIM_KEY_APPID).toString();
        } catch (Exception e) {
            log.error("getAppidFromToken error:",e);
            appid = null;
        }
        return appid;
    }
    /**
     * 从token中获取登录用户名
     */
    public String getUseridFromToken(String token) {
        String userid;
        try {
            Claims claims = getClaimsFromToken(token);
            userid = claims.get(CLAIM_KEY_USERID)==null? "" : claims.get(CLAIM_KEY_USERID).toString();
        } catch (Exception e) {
            log.error("getUseridFromToken error:",e);
            userid = null;
        }
        return userid;
    }
 
    public Claims getClaim(String token) {
        try {
            Claims claims = getClaimsFromToken(token);
            return claims;
        } catch (Exception e) {
            log.error("getClaim error:",e);
            return null;
        }
    }
 
    /**
     * 验证token是否还有效
     *
     * @param token       客户端传入的token
     * @param userDetails 从数据库中查询出来的用户信息
     */
    public boolean validateToken(String token, UserDetails userDetails) {
        String key= GlobalConst.TOKEN_KEY+userDetails.getUsername();
        String tmpKey= GlobalConst.TOKEN_KEY_TMP+userDetails.getUsername();
        Object useridobject = getClaim(token).get(JwtTokenUtil.CLAIM_KEY_USERID);
        if(!Objects.isNull(useridobject)){
            key +=":"+useridobject.toString();
            tmpKey +=":"+useridobject.toString();
        }
        return (redisUtil.get(key) !=null && token.equals(redisUtil.get(key).toString()) && !isTokenExpired(token))
                ||(redisUtil.get(tmpKey) !=null && token.equals(redisUtil.get(tmpKey).toString()) && !isTokenExpired(token));
    }
 
    /**
     * 判断token是否已经失效
     */
    private boolean isTokenExpired(String token) {
        Date expiredDate = getExpiredDateFromToken(token);
        return expiredDate.before(new Date());
    }
 
    /**
     * 从token中获取过期时间
     */
    private Date getExpiredDateFromToken(String token) {
        Claims claims = getClaimsFromToken(token);
        return claims.getExpiration();
    }
 
    /**
     * 根据用户信息生成token
     */
    public String generateToken(AppDetails userDetails) {
        Map<String, Object> claims = new HashMap<>();
        claims.put(CLAIM_KEY_APPID, userDetails.getUsername());
        if(StringUtils.isNotEmpty(userDetails.getUserid())){
            claims.put(CLAIM_KEY_USERID, userDetails.getUserid());
 
        }
        claims.put(CLAIM_KEY_CREATED, new Date());
        return generateToken(claims);
    }
 
    /**
     * 判断token是否可以被刷新
     */
    public boolean canRefresh(String token) {
        return !isTokenExpired(token);
    }
 
    /**
     * 刷新token
     */
    public String refreshToken(String token) {
        Claims claims = getClaimsFromToken(token);
        claims.put(CLAIM_KEY_CREATED, new Date());
        return generateToken(claims);
    }
}