第一部分为头部(header),第二部分我们称其为载荷(payload),第三部分是签证(signature)。【中间用 . 分隔】
一个标准的JWT生成的token格式如下:Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjUwMCwicmlkIjowLCJpYXQiOjE2MjYzOTgwNDMsImV4cCI6MTYyNjQ4NDQ0M30.ojaiFvsGQew4SbbTakvwO2qv7TAWNgWk6GyvmIRdYV8
2. 话不多说,直接上项目截图
3. 首先导入JWT依赖(POM文件)
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.16.0</version>
</dependency>
4.写一个工具类JwtUtil,用来生成token
private static String SIGN="!QQW#ERP";//这个是密钥,千万不要泄露,可以自己随意设置
/**
* 生成token header.payload.sign
*/
public static String getToken(Map<String,String> map){
//设置令牌过期时间 7天
Calendar instance=Calendar.getInstance();
instance.add(Calendar.DATE,7);
//创建jwt builder
JWTCreator.Builder builder=JWT.create();
//payload
map.forEach((k,v)->{
builder.withClaim(k,v);
});
String token = builder.withExpiresAt(instance.getTime())
.sign(Algorithm.HMAC256(SIGN));
return token;
}
/**
* token验证 合法性
*/
public static void verify(String token){
JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
}
/**
* 获取token信息方法
*/
public static DecodedJWT getTokenInfo(String token){
DecodedJWT verify = JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
return verify;
}
/**
* 获取key字段的值
*/
public static String getInfoByToken(String token, String key) {
//String value = getTokenInfo(token).getClaim(key).toString();
写法相同
String value = getTokenInfo(token).getClaims().get(key).asString();
value = value.replace("\"", "").replace("\"", "");
return value;
}
/**
* 获取当前用户id
*
* @return
*/
public static String getId() {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
String token = request.getHeader("token");
DecodedJWT verify = JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
String id = verify.getClaims().get("id").asString();
//String id = verify.getClaim("id").toString();
return id;
}
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Map<String,Object> map=new HashMap<>();
//获取请求头中的令牌
String token = request.getHeader("token");
try{
JwtUtil.getTokenInfo(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);
String json = new ObjectMapper().writeValueAsString(map);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().println(json);
return false;
}
@PostMapping("/login")
public Map<String,Object> login(String userName,String password){
Users users=new Users();//由于并没用到数据库,所以controller写死数据了
users.setId("1001");
users.setUserName(userName);
users.setPassword(password);
Map<String,Object> map=new HashMap<>();
try{
Map<String,String> payload=new HashMap<>();
payload.put("id",users.getId());
payload.put("userName",users.getUserName());
payload.put("password",users.getPassword());
String token = JwtUtil.getToken(payload);
map.put("state",true);
map.put("msg","认证成功");
map.put("token",token);
}catch (Exception e){
map.put("stste",false);
map.put("msg",e.getMessage());
}
return map;
}
@PostMapping("/test")
public String test(){
return "拦截器不拦截我";
}
7.创建一个实体类Users,由于并没用到数据库,所以controller写死数据了,自己写get()、set()方法
@Data
public class Users {
private String id;
private String userName;
private String password;
}
8.这时候发现login和test都不进行token验证,login肯定不能进行验证,login用于生成token,但是进入test应该验证,所以创建拦截器InterceptorConfig
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new JWTInterceptor())
.addPathPatterns("/**") //拦截test
.excludePathPatterns("/login");//排除登录,其他拦截
}
}
结束