首先,介绍一下什么是JWT
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).定义了一种简洁的,自包含的方法用于通信双方之间以JSON对象的形式安全的传递信息。因为数字签名的存在,这些信息是可信的,JWT可以使用HMAC算法或者是RSA的公私秘钥对进行签名
JWT请求流程
1. 用户使用账号密码发出post请求;
2. 服务器使用私钥创建一个jwt;
3. 服务器返回这个jwt给浏览器;
4. 浏览器将该jwt串在请求头中像服务器发送请求;
5. 服务器验证该jwt;
6. 返回响应的资源给浏览器。
JWT标准的Token有三个部分组成,分别是
header:header 部分主要是两部分内容,一个是 Token 的类型,另一个是使用的算法,比如下面类型就是 JWT,使用的算法是 HS256,就是SHA-256,和md5一样是不可逆的散列算法。
payload:Payload 里面是 Token 的具体内容
signature:签名,在服务器端,用签名做token校验
springboot整合JWT
引入需要的依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.10.3</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>5.1.32</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
JWT 工具类
public class JWTUtils {
//签名 自己项目中的签名
private static final String SIGN = "token!@19weawe2r24@#$@%!wewa98du";
public static String getToken(Map<String, String> claim) {
JWTCreator.Builder builder = JWT.create();
claim.forEach((key, value) -> {
builder.withClaim(key, value); //设置payload
});
Calendar instance = Calendar.getInstance();
instance.add(Calendar.DAY_OF_MONTH, 7);
builder.withExpiresAt(instance.getTime()); //设置token过期时间
return builder.sign(Algorithm.HMAC256(SIGN));
}
public static DecodedJWT verifyToken(String token) {
return JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
}
}
使用拦截器拦截处理token
@Component
public class JWTInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader("token");
HashMap<String, Object> map = new HashMap<>();
try {
JWTUtils.verifyToken(token);
return true;
} catch (SignatureVerificationException e) {
e.printStackTrace();
map.put("msg","无效的签名");
}catch (TokenExpiredException e){
e.printStackTrace();
map.put("msg","该令牌已过期");
}catch (AlgorithmMismatchException e){
e.printStackTrace();
map.put("msg","算法不匹配");
}catch (Exception e){
e.printStackTrace();
map.put("msg","token无效!");
}
map.put("status",false);
String errorMsg = JSONObject.toJSONString(map);
response.setContentType("application/json; charset=UTF-8");
PrintWriter writer = response.getWriter();
writer.print(errorMsg);
writer.close();
return false;
}
}
开启拦截器
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Autowired
private JWTInterceptor jwtInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor)
.addPathPatterns("
@PostMapping("/login")
public Map<String, Object> login(User user, HttpServletRequest request) {
HashMap<String, Object> map = new HashMap<>();
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("username", user.getUsername());
wrapper.eq("password", user.getPassword());
try {
User currUser = userMapper.selectOne(wrapper);
HashMap<String, String> claim = new HashMap<>();
claim.put("id",currUser.getId());
claim.put("username",currUser.getUsername());
String token = JWTUtils.getToken(claim);
map.put("status",true);
map.put("msg","认证成功");
map.put("token",token);
return map;
} catch (Exception e) {
map.put("status",false);
map.put("msg","认证失败");
return map;
}
}
最后写一个接口测试一下
@GetMapping
public String get(){
return "成功请求";
}
当不携带token访问该接口时
认证获取token
携带token 访问测试接口
请求成功!!!
使用ajax携带token
$.ajax({
headers: {
"token":token
},
type: "get",
url: "/test/getMessage",
contentType: "application/x-www-form-urlencoded",
})
这世上没有天才,你若对得起时间,时间便对得起你。让我们一起携手共进,每天进步一点点,利用碎片化时间学习。