JWT的入门学习和JWTUtils封装
前面学习了JWT,并且已经成功的把JWT封装成了工具类
在现实中的前后端分离项目中,我们一般都是集合Springboot进行整合,所现在我们就与Springboot项目进行整合
JWT工作流程图
在登录请求上生成token并让其返回给前端
package com.jwttest.controller;
import com.jwttest.utils.JWTUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/login")
public Map<String, Object> login(String username, String password){
//为了清晰的实现逻辑,这里不连接数据库了,直接对字符串进行验证
System.out.println(username+"---");
System.out.println(password);
Map<String, Object> map = new HashMap<>();
if("Mark".equals(username) && "123".equals(password)){
Map<String, String> payload = new HashMap<>();
int id = 111111;//这个可以是从数据库中找到的用户ID
//生成JWT令牌
payload.put("id", Integer.toString(id));
payload.put("username",username);
String token = JWTUtils.getToken(payload);
map.put("state", true);
map.put("msg","认证成功");
map.put("token",token);
}else{
map.put("state", false);
map.put("msg", "认证失败");
}
return map;
}
@GetMapping("/welcome")
public Map<String,String> test(){
//在
Map<String, String> map = new HashMap<>();
map.put("msg","请求成功,可以处理自己的业务逻辑");
return map;
}
}
写了两个请求,一个是登录请求,用户名和密码通过验证后封装成一个Token,token再和一些其它信息放回给前端。
按照正常的业务逻辑,我们知道在访问其它接口时都要携带token,我们虽然可以在每个接口上封装一个token参数,然后用前端传入过来,可是这样 太过冗余,在这里,我们可以使用拦截器来实现这个功能
新建一个拦截器
package com.jwttest.interceptors;
import ch.qos.logback.core.encoder.EchoEncoder;
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.jwttest.utils.JWTUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.SignatureException;
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 {
String token = request.getHeader("token");
Map<String, Object> map = new HashMap<>();
try{
JWTUtils.verify(token);
return true;
}catch (SignatureVerificationException e){
e.printStackTrace();
map.put("msg", "无效签名");
}catch (TokenExpiredException e){
map.put("msg", "token过期");
}catch (AlgorithmMismatchException e){
map.put("msg", "token算法不一致");
}catch (Exception e){
e.printStackTrace();
map.put("msg", "token无效");
}
map.put("state", false);
//将Map转为Json
String json = new ObjectMapper().writeValueAsString(map);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().println(json);
return false;
}
}
配置拦截器
package com.jwttest.config;
import com.jwttest.interceptors.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 Interceptors implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new JWTInterceptor())
.addPathPatterns("/user/**")
.excludePathPatterns("/user/login");
}
}
进行测试
- 访问login接口
情况1(用户名正确,返回token)
情况2(登录失败)
- 访问其它接口
情况1(没有携带token或者没有携带正确的token)
情况2(携带了正确token)
一般情况下token是放在header,请求头上的