JWT如何生成token?
token如何验签?
springboot中如何使用JWT?
如果你对JWT的概念不了解,建议先阅读JWT的介绍,以方便对JWT的构成有清晰的认识,当然这并不影响你对JWT的使用。
详细可以查看 JWT(1): JWT介绍
英文较好的可以查阅官方的介绍:https://jwt.io/introduction
<dependency>
<groupId>com.auth0groupId>
<artifactId>java-jwtartifactId>
<version>4.0.0version>
dependency>
@Test
public void testJWTCreate(){
String token=createToken();
System.out.println(token);
}
public String createToken(){
Calendar instance=Calendar.getInstance();
instance.add(Calendar.SECOND,60);
//默认包header加密是HS256,通常不需要设置
// JWT.create().withHeader()
HashMap<String,Object> map=new HashMap<>();
String token= JWT.create()
.withHeader(map)
.withClaim("userId",1) //指定用户信息
.withClaim("name","xiaowang") //指定用户名
.withExpiresAt(instance.getTime()) //指定过期时间
.sign(Algorithm.HMAC256("%sabs*!3ja"));//签名
return token;
}
运行结果

@Test
public void testVerification(){
String token=createToken();
JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256("%sabs*!3ja")).build();
DecodedJWT verify=jwtVerifier.verify(token);//解析jwt
System.out.println(verify.getClaims());
}
运行结果


package com.it2.springbootjwt.util;
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.Map;
/**
* JWT
*/
public class JWTUtils {
/**
* 密钥
*/
private static final String SECRET = "FTIq]>h!>2H-zd_";
/**
* 生成token
*
* @param map
* @param amount 有效期秒
* @return
*/
public static String createToken(Map<String, String> map, Integer amount) {
Calendar instance = Calendar.getInstance();
/**
* 签名失效时间如果不传递,则默认7天
*/
amount = (null == amount || amount < 1) ? 7 * 24 * 60 * 60 : amount;
instance.add(Calendar.SECOND, amount);
//默认包header加密是HS256,通常不需要设置
JWTCreator.Builder builder = JWT.create();
map.forEach((k, v) -> {
builder.withClaim(k, v);
});
String token = builder.withExpiresAt(instance.getTime()) //指定过期时间
.sign(Algorithm.HMAC256(SECRET));//签名
return token;
}
/**
* 验签
*
* @param token
*/
public static void vertifyToken(String token) {
getTokenInfo(token);
}
/**
* 获取token信息
*
* @param token
*/
public static DecodedJWT getTokenInfo(String token) {
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
DecodedJWT verify = jwtVerifier.verify(token);//解析jwt
return verify;
}
}
package com.it2.springbootjwt.controller;
import com.it2.springbootjwt.pojo.User;
import com.it2.springbootjwt.service.UserService;
import com.it2.springbootjwt.util.JWTUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
@Slf4j
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/user/login")
public Map<String, Object> login( String username,String password) {
log.info("用户名:{},密码:{}", username, password);
Map<String, Object> map = new HashMap<>();
try {
User user2 = userService.login(username,password);
Map<String, String> payload = new HashMap<>();
payload.put("userid", user2.getId() + "");
payload.put("username", user2.getUsername());
String token = JWTUtils.createToken(payload, null);
map.put("token", token);
map.put("code", "ok");
map.put("msg", "登录成功");
} catch (Exception e) {
map.put("code", "fail");
map.put("msg", "登录失败");
}
return map;
}
}
package com.it2.springbootjwt.pojo;
import lombok.Data;
@Data
public class User {
private Integer id;
private String username;
private String password;
}


我们的业务在执行的时候,显然需要编写token是否有效,但是这明显不可能放在各个业务中去鉴定。
所以我们需要使用拦截器,拦截器可以在业务执行前判断请求的token是否有效。
package com.it2.springbootjwt.interceptor;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.it2.springbootjwt.util.JWTUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
/**
* JWT拦截器
*/
@Slf4j
public class JWTInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Map<String, Object> map = new HashMap<>();
String token = request.getHeader("token");
try {
JWTUtils.vertifyToken(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", "签名算法不匹配");
} catch (Exception e) {
e.printStackTrace();
map.put("msg", "token无效");
}
map.put("code", false);
String jsonString = JSONObject.toJSONString(map);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().println(jsonString);
return false;
}
}
package com.it2.springbootjwt.config;
import com.it2.springbootjwt.interceptor.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("/*/*") //其它业务接口
.excludePathPatterns("/user/login");//排除不拦截的接口
}
}
package com.it2.springbootjwt.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class HelloController {
@GetMapping("/hello/sayHello")
public String sayHello() {
log.info("sayhello....");
return "success";
}
}


显然我们在执行业务时,有时候需要获取用户的信息。那么我们可以通过header中获取。
@GetMapping("/hello/sayHello")
public String sayHello(HttpServletRequest request) {
String token= request.getHeader("token");
DecodedJWT jwt=JWTUtils.getTokenInfo(token);
System.out.println( jwt.getClaim("username").asString());
System.out.println( jwt.getClaim("userid").asString());
log.info("sayhello....");
return "success";
}
运行结果
