kongzy
2024-07-12 28aaf2ffa1dbb860a292ba330a7e9362e60e7832
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
package com.gkhy.assess.common.utils;
 
import cn.hutool.core.date.DateUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gkhy.assess.common.api.CommonResult;
import com.gkhy.assess.common.exception.ApiException;
import io.swagger.models.auth.In;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
 
/**
 * JwtToken生成的工具类
 * JWT token的格式:header.payload.signature
 * header的格式(算法、token的类型):
 * {"alg": "HS512","typ": "JWT"}
 * payload的格式(用户名、创建时间、生成时间):
 * {"sub":"wang","created":1489079981393,"exp":1489684781}
 * signature的生成算法:
 * HMACSHA512(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)
 */
public class JwtTokenUtil {
    private static final Logger LOGGER = LoggerFactory.getLogger(JwtTokenUtil.class);
 
    public static final String USER_LOGIN_TOKEN="Authorization";
 
    public static final String CLAIM_KEY_USERNAME = "sub";
    public static final String CLAIM_KEY_CREATED = "created";
 
    public static String SECRET="nms-secret";
 
    public static String tokenHead="";
 
    /**Token有效期为1天(Token在reids中缓存时间为两倍)  单位ms*/
    public static final long EXPIRATION=(1 *12) * 60 * 60 * 1000;  //JWT的超期限时间(60*60*24*1)
 
    /**
     * token有效期还有30分钟,刷新token  单位ms
     */
    public static final long NEED_UPDATE_TIME= 30 * 60 * 1000;
 
    /**
     * 校验token是否正确
     * @param token
     * @param username
     * @param secret  用户密码
     * @return
     */
    public static boolean verify(String token,String username,String secret,Integer identity){
        try {
            Algorithm algorithm = Algorithm.HMAC256(secret);
            JWTVerifier verifier = JWT.require(algorithm).withClaim("username", username)
                    .withClaim("identity",identity).build();
            DecodedJWT jwt = verifier.verify(token);
            return true;
        }catch (Exception e){
            return false;
        }
    }
 
 
    public static boolean isNeedUpdate(String token, String username, String secret,Integer identity){
        Date expertsAt =null;
        try {
            Algorithm algorithm = Algorithm.HMAC256(secret);
            JWTVerifier verifier = JWT.require(algorithm).withClaim("username", username)
                    .withClaim("identity",identity).build();
            expertsAt = verifier.verify(token).getExpiresAt();
        }catch (Exception e){
            throw new ApiException("token非法无效");
        }
        //如果剩余过期时间少于过期时常的一半时 需要更新
        return (expertsAt.getTime()-System.currentTimeMillis()) < NEED_UPDATE_TIME;
    }
 
    /**
     * 获取token中的信息  无需secret解密也能获得
     * @param token
     * @return
     */
    public static String getUsername(String token){
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("username").asString();
        }catch (JWTDecodeException e){
            return null;
        }
    }
 
    /**
     * 获取token中的信息  无需secret解密也能获得
     * @param token
     * @return
     */
    public static Integer getIdentity(String token){
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("identity").asInt();
        }catch (JWTDecodeException e){
            return null;
        }
    }
 
 
 
    /**
     * 生成签名
     * @param username
     * @param secret
     * @return
     */
    public static String sign(String username,String secret,Integer identity){
        Date date=new Date(System.currentTimeMillis()+EXPIRATION);
        Algorithm algorithm=Algorithm.HMAC256(secret);
        return JWT.create().withClaim("username",username)
                .withClaim("identity",identity).withExpiresAt(date).sign(algorithm);
    }
 
    /**
     * 根据request中的token获取用户账号
     *
     * @param request
     * @return
     * @throws ApiException
     */
    public static String getUserNameByToken(HttpServletRequest request) throws ApiException {
        String accessToken = request.getHeader(USER_LOGIN_TOKEN);
        String username = getUsername(accessToken);
        if (StringUtils.isEmpty(username)) {
            throw new ApiException("未获取到用户");
        }
        return username;
    }
 
 
    /**
     * md5加密
     * @param token
     * @return
     */
    public static String md5Encode(String token){
 
        return DigestUtil.md5Hex(token);
    }
 
 
    /**
     * 密码加密
     * @param username
     * @param password
     * @param salt
     * @return
     */
    public static String encryptPassword(String username,String password,String salt){
        if(salt==null){
            salt="";
        }
        return new Md5Hash(username+password+salt).toHex();
    }
 
 
    /**
     *
     * @param response
     * @param code
     * @param errorMsg
     */
    public static void responseError(ServletResponse response, String errorMsg) {
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        // issues/I4YH95浏览器显示乱码问题
        httpServletResponse.setHeader("Content-type", "text/html;charset=UTF-8");
        CommonResult jsonResult = CommonResult.failed(errorMsg);
        OutputStream os = null;
        try {
            os = httpServletResponse.getOutputStream();
            httpServletResponse.setCharacterEncoding("UTF-8");
         //   httpServletResponse.setStatus(code);
            os.write(new ObjectMapper().writeValueAsString(jsonResult).getBytes("UTF-8"));
            os.flush();
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
 
 
}