【SpringBoot】拦截器处理JWT验证
发布日期:2021-06-29 21:37:46
浏览次数:2
分类:技术文章
本文共 6357 字,大约阅读时间需要 21 分钟。
在上文中,我们已经了解到了JWT并进行了实现,但是在每个接口都进行验证会使得代码非常冗余,因此本文中,我们将结合SpringBoot2.x进行整合,将JWT验证放到拦截器中进行实现。 |
JWT认证流程图如下:
创建包结构:
Maven依赖信息:com.auth0 java-jwt 3.11.0 com.alibaba fastjson 1.2.28 io.jsonwebtoken jjwt 0.9.0
TestController 代码:
package com.dl.jwt.controller;import com.auth0.jwt.interfaces.DecodedJWT;import com.dl.jwt.utils.JavaJWTUtil;import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletRequest;import java.util.HashMap;import java.util.Map;@Controller@RequestMapping("/manage/")@Slf4jpublic class TestController { @ResponseBody @RequestMapping(value = "login.do",method = RequestMethod.GET) public Maplogin(String userid,String password){ /** *验证逻辑为了简便这里就不去做了 **/ //后端数据库校验成功 Map payload=new HashMap<>(); payload.put("username","dingli"); payload.put("userid",userid); String token= JavaJWTUtil.getToken(payload,30); Map map=new HashMap<>(); map.put("state",true); map.put("msg","认证成功!"); map.put("token",token); log.info("认证token为:{}",token); return map; } @ResponseBody @RequestMapping(value = "test.do",method = RequestMethod.POST) public Map test(HttpServletRequest request){ Map map=new HashMap<>(); String token=request.getHeader("token");//缓存在客户端,只要没过期,即使服务端重启也可以认证成功 DecodedJWT verify=JavaJWTUtil.verify(token); System.out.println("用户id:"+verify.getClaim("userid").asString()); map.put("state",true); map.put("msg","请求成功!"); return map; }}
自定义JWT拦截器(JWTIntercepter )代码
package com.dl.jwt.intercepters;import com.alibaba.fastjson.JSONObject;import com.auth0.jwt.exceptions.AlgorithmMismatchException;import com.auth0.jwt.exceptions.InvalidClaimException;import com.auth0.jwt.exceptions.SignatureVerificationException;import com.auth0.jwt.exceptions.TokenExpiredException;import com.auth0.jwt.interfaces.DecodedJWT;import com.dl.jwt.utils.JavaJWTUtil;import com.fasterxml.jackson.databind.ObjectMapper;import lombok.extern.slf4j.Slf4j;import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.util.HashMap;import java.util.Map;/** * 自定义拦截器验证token */@Slf4jpublic class JWTIntercepter implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Mapmap=new HashMap<>(); String token=request.getHeader("token");//获取请求头中的token log.info("当前token为:{}",token); try{ JavaJWTUtil.verify(token);//验证token return true;//验证通过,就会去controller请求数据了 }catch(SignatureVerificationException ex){ ex.printStackTrace(); map.put("msg","无效签名!"); }catch(TokenExpiredException ex){ ex.printStackTrace(); map.put("msg","token过期!"); }catch(AlgorithmMismatchException ex){ ex.printStackTrace(); map.put("msg","token算法不一致"); }catch(Exception ex){ ex.printStackTrace(); map.put("msg","token无效!"); } map.put("state",false); //String jsonObject =new ObjectMapper().writeValueAsString(map); //采用jackson //将map转为json采用 fastjackson String jsonObject= JSONObject.toJSONString(map); response.setContentType("application/json;charset=UTF-8"); response.getWriter().println(jsonObject);//错误信息发送回前台 return false; }}
创建实现WebMvcConfigurer接口的配置类把拦截器添加到拦截器链中,WebMvcConfig代码:
package com.dl.jwt.config;import com.dl.jwt.intercepters.JWTIntercepter;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configurationpublic class WebMvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new JWTIntercepter()) .addPathPatterns("/manage/**") //拦截/manage请求下的所有请求 .excludePathPatterns("/manage/login.do"); //登录请求拦截 }}
JavaJwtUtil代码:
import com.auth0.jwt.JWT;import com.auth0.jwt.JWTCreator;import com.auth0.jwt.algorithms.Algorithm;import com.auth0.jwt.interfaces.DecodedJWT;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Component;import java.util.Calendar;import java.util.Map;public class JavaJWTUtil { private static String secret="csdntonghuasdfni#2323!@seirninfsasdf";//这个secret我们一般写在配置文件或者存放常量的类中,这里为了方便直接写在这儿 /** * 生成token header.payload.signature * @param map :payload中需要存放的信息,以map方式传入 * @param day :过期时间,以秒为单位 * @return */ public static String getToken(Mapmap,Integer day){ Calendar instance=Calendar.getInstance(); instance.add(Calendar.SECOND,day); //创建jwt builder JWTCreator.Builder builder=JWT.create(); //payload,这里采用lambda表达式设置 map.forEach((k,v)->{ builder.withClaim(k,v); }); String token=builder.withExpiresAt(instance.getTime())//指定令牌过期时间 .sign(Algorithm.HMAC256(secret)); return token; } /** * 验证token合法性,不合法会抛出异常信息 * @param token : 前端传来的token * @return */ public static DecodedJWT verify(String token){ //如果有任何验证异常,此处都会抛出异常,因此我们可以捕获这些异常来反馈信息回前端 DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC256(secret)).build().verify(token); return decodedJWT; }}
采用Postman进行接口测试
登录请求生成token接口示例: 验证token请求示例,/manage下的非登录请求,上面生成的token添加到请求头中转载地址:https://dh-butterfly.blog.csdn.net/article/details/110003775 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
很好
[***.229.124.182]2024年04月29日 02时56分25秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
IIS web site windows验证
2019-04-30
.Net Mvc PagedList
2019-04-30
vue--学习一
2019-04-30
C# string[] 转list<long>
2019-04-30
sql server解析xml字段
2019-04-30
vue学习一
2019-04-30
基于Jenkins的.Net Core应用自动部署--学习一
2019-04-30
bootstrap-vue
2019-04-30
C# WebUtils
2019-04-30
ETL
2019-04-30
CR(变更请求)
2019-04-30
MVC是什么
2019-04-30
使用C#创建Windows服务
2019-04-30
Visual Studio 命令行wsdl生成C#操作类
2019-04-30
easyui-dialog
2019-04-30
jquery.显示隐藏切换
2019-04-30
C# Dictionary 是否包含key
2019-04-30
C#计算两个时间年份月份差&计算两个日期的时间间隔
2019-04-30
BI与ETL
2019-04-30
超级实用但很少人知道的 VS 技巧[更新]
2019-04-30