官方网址:https://jwt.io/introduction/
json web token(JWT)是一个开放标准(RFC7519),他定义了一种紧凑的、自包含的方式,用于在各方之间以JSON对象安全地址传输信息。此信息可以验证和信任,因为他是数字签名的。JWT可以使用秘密(HMAC算法)或使用RSA或ECDSA的公钥/私钥对进行签名。
标头可以不写,有效负荷就是要把哪些内容存到token里面去,签名就是通过1和2或者2使用JWT加密类生成一个token返回给前端,前端之后的每个请求都要携带这个token
第一步 :引入依赖
<!---jwt-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
第二步 JWT生成和解析token工具类
package com.rong.utils;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Calendar;
import java.util.Iterator;
import java.util.Map;
public class JWTUtils {
private static final String SIGN ="nihao";
// 通过控制层传过来的有效负荷生成token
public static String generateToken(Map<String, String> map){
Calendar instance = Calendar.getInstance();
instance.add(Calendar.SECOND,1000);
JWTCreator.Builder builder = JWT.create();
Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
while (iterator.hasNext()){
Map.Entry<String, String> entry = iterator.next();
builder.withClaim(entry.getKey(),entry.getValue());
}
String token = builder.withExpiresAt(instance.getTime())
.sign(Algorithm.HMAC256(SIGN));
return token;
}
// 根据令牌和签名解析数据(解析前端传过来的token)
public static DecodedJWT verify(String token){
JWTVerifier build = JWT.require(Algorithm.HMAC256(SIGN)).build();
DecodedJWT decodedJWT = build.verify(token);
return decodedJWT;
}
}
第三步 配置JWT拦截器:验证前端传过来的token信息
package com.rong.utils;
import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
public class JWTInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Map<String, Object> map = new HashMap<>();
try {
//本系统默认前端把token放到了请求头中,key为token
String token = request.getHeader("token");
JWTUtils.verify(token);
return true;
} catch (SignatureVerificationException e) {
e.printStackTrace();
map.put("msg","无效签名");
}catch (TokenExpiredException e) {
e.printStackTrace();
map.put("msg","token过期");
}catch (AlgorithmMismatchException e) {
e.printStackTrace();
map.put("msg","token算法不一致");
}catch (Exception e) {
e.printStackTrace();
map.put("msg","token无效");
}
map.put("state",false); //这设置状态
response.setContentType("application/json;charset=UTF-8");
String token = new ObjectMapper().writeValueAsString(map);
response.getWriter().println(token);
return false;
}
}
第四步 配置拦截器交给spring管理并配置请求路径
package com.rong.config;
import com.rong.utils.JWTInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new JWTInterceptor())
.addPathPatterns("/rong/user/test") //其他接口token验证
.excludePathPatterns("/rong/user/login"); //所有用户都放行
}
}