一、具体操作
具体参照这篇
二、几点补充
1、引入Jwt依赖
复制代码
1
2
3
4
5
6<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt --> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.7.0</version> </dependency>
2、在filter中验证token时,过期和非法的token都会抛出异常,可以自定义bean继承自BasicErrorController来进行统一的异常处理(返回给前端固定的Json内容,实际使用时和Js交互还会遇到跨域问题,要给response加上相关的请求头)。
3、贴波自己写的代码
注:基于 boot 1.X, 2.X的BasicErrorController有所不同
不懂的留言
复制代码
1
2
3
4
5
6
7
8
9
10
11@Configuration public class JwtConfig { @Bean public FilterRegistrationBean jwtFilter() { final FilterRegistrationBean registrationBean = new FilterRegistrationBean(); registrationBean.setFilter(new JwtFilter()); registrationBean.addUrlPatterns("/test/*");//配置对应路径的接口使用此 filter return registrationBean; } }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54@RestController public class MyCommonErrorController extends BasicErrorController { //统一处理filter抛出的token相关的异常 返回给前端标准格式的json和装填码 private static final String PATH = "/error"; private static final String TOKEN_MISS = "Missing or invalid Authorization header"; private static final String TOKEN_EXPIRED = "token expired"; private static final String TOKEN_INVALID = "token invalid"; private static final String TOKEN_ERROR = "error"; public MyCommonErrorController() { super(new DefaultErrorAttributes(), new ErrorProperties()); } @Override @RequestMapping( produces = {"application/json"} ) public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) { //加入跨域相关内容 HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Expose-Headers", "X-Total-Count"); response.setHeader("Access-Control-Allow-Headers", "origin, x-requested-with, x-http-method-override, content-type, Authentication, Authorization, hospital"); response.setHeader("Access-Control-Allow-Methods", "PUT, GET, POST, DELETE, OPTIONS, HEAD, PATCH"); HttpStatus status = this.getStatus(request); Map<String, Object> errorAttributes = this.getErrorAttributes(request, true); String message = (String)errorAttributes.get("message"); Map<String, Object> body = new LinkedHashMap<>(16); body.put("code", getCode(message)); body.put("message", message); body.put("data", null); return new ResponseEntity(body, status); } private int getCode(String msg){ if (TOKEN_MISS.equals(msg)){ return -1; }else if (TOKEN_EXPIRED.equals(msg)){ return -2; }else if (TOKEN_INVALID.equals(msg)){ return -3; }else if (TOKEN_ERROR.equals(msg)){ return -4; }else { return -5; } } @Override public String getErrorPath() { return PATH; } }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23@RestController public class TokenController { //登陆接口 @PostMapping("/login") public Object login(@RequestBody LoginRequest loginRequest){ //假设验证过了用户名和密码 发token // Create Twt token return generateToken(loginRequest.getUsername()); } private String generateToken(String username) { Map<String, Object> claims = new HashMap<>(16); claims.put("sub", username); claims.put("created", new Date()); return generateToken((claims)); } private String generateToken(Map<String, Object> claims) { return Jwts.builder().setClaims(claims) //payload .setExpiration(new Date(System.currentTimeMillis() + 60 * 1000L)) //过期时间 .signWith(SignatureAlgorithm.HS512, "nicai").compact(); //加密方式 } }
复制代码
1
2
3
4
5
6
7
8
9
10
11@RestController @RequestMapping("/test") public class TestController { //用于测试token的验证 @GetMapping("") public Object getTest(HttpServletRequest request){ System.out.println(request.getAttribute("claims")); Map<String, String> claims = (Map<String, String>) request.getAttribute("claims"); return "test"; } }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15@Data public class TokenException extends Exception { //自定义异常类型 private int code; private String msg; public TokenException() { } public TokenException(int code, String msg) { super(msg); this.code = code; this.msg = msg; } }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39public class JwtFilter extends GenericFilterBean{ //Jwtconfig中配置的filter 用于Jwt token的验证工作 配置时可以指定对应的路径 @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { final HttpServletResponse response = (HttpServletResponse) servletResponse; final HttpServletRequest request = (HttpServletRequest) servletRequest; String authHeader = request.getHeader("Authorization"); //规避探测性质的 OPTIONS请求 String optionsString = "OPTIONS"; String bearerString = "Bearer "; if (optionsString.equals(request.getMethod())){ response.setStatus(HttpServletResponse.SC_OK); filterChain.doFilter(servletRequest, servletResponse); }else { //验证token if (StringUtils.isEmpty(authHeader) || !authHeader.startsWith(bearerString)){ throw new ServletException(new TokenException(-1, "Missing or invalid Authorization header")); }else { String token = authHeader.substring(bearerString.length()); try { //使用jwt paser来验证签名 Claims claims = Jwts.parser().setSigningKey("nicai").parseClaimsJws(token).getBody(); request.setAttribute("claims", claims); }catch (ExpiredJwtException e){ throw new ServletException(new TokenException(-2, "token expired")); }catch (SignatureException e){ throw new ServletException(new TokenException(-3, "token invalid")); }catch (Exception e){ throw new ServletException(new TokenException(-4, "error")); } } filterChain.doFilter(servletRequest, servletResponse); } } }
最后
以上就是光亮乌冬面最近收集整理的关于spring-boot Jwt实现token的发放和验证的全部内容,更多相关spring-boot内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复