目录
- 下发JWT 令牌
- 依赖文件
- 令牌生成
- 令牌验证
- 统一验证技术
- 过滤器 Filter
- 快速使用
- 实现登录校验
- 拦截器 Interceptor
- 快速使用
- 实现登录校验
下发JWT 令牌
全称: JSON Web Token
官网: https://jwt.io/
以JSON 的数据格式安全传输信息,利用 base64 进行编码。
组成:
第一部分:Header (头),记录 签名算法 ,令牌类型 。
例如:{“alg”: “HS256”,“type”: “JWT”}
第二部分:Payload (有效载荷),携带自定义信息 ,一般为登录 账号 和 密码。
第三部分:Signature 防止 被篡改 将 header,payload,并加入指定密钥,通过指定签名算法计算而来。
依赖文件
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency><!-- java 9 以上需要引入 --><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.1</version></dependency><dependency><groupId>org.glassfish.jaxb</groupId><artifactId>jaxb-runtime</artifactId><version>2.3.1</version></dependency>
令牌生成
HashMap<String, Object> hashMap = new HashMap<>();hashMap.put("name", "lisi");hashMap.put("password", "1234");
String jwt = Jwts.builder()
/*sign 签名算法*/.signWith(SignatureAlgorithm.HS256, "ssstfthm") //sign 签名算法
/* 自定义内容 */ .setClaims(hashMap) // 自定以内容
/*过期时间*/ .setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000)) .compact(); //生成令牌System.out.println(jwt);
令牌验证
Claims :可以像遍历一个 Map 一样遍历 Claims 对象中的所有声明。例如,可以使用 for (Map.Entry<String, Object> entry : claims.entrySet()) 来遍历所有声明,并访问它们的键和值。
String token = "eyJhbGciOiJIUzI1NiJ9.eyJwYXNzd29yZCI6IjEyMzQiLCJuYW1lIjoibGlzaSIsImV4cCI6MTczNTQ4NzczMH0.JnQhXvsx0ZOsrPrtrUmkZ-RLCaVgwP8dgrS6nArF-vQ";Claims claims = Jwts.parser().setSigningKey("ssstfthm") //设置签名.parseClaimsJws(token) //令牌内容.getBody(); System.out.println(claims);
统一验证技术
过滤器 Filter
JavaWeb 三大组件之一 (Servlet , Filter ,Listener) 之一
一般完成 通用的操作,比如:登录校验,统一编码,敏感字符处理
快速使用
多个 过滤器 按类名排序
1.创建过滤器类
javax.servlet.Filter
@WebFilter(urlPatterns = "/*") //配置拦截路径
public class FilterDemo implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("过滤器创建");Filter.super.init(filterConfig);}@Overridepublic void destroy() {System.out.println("过滤器销毁");Filter.super.destroy();}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("过滤器 拦截");// 放行操作filterChain.doFilter(servletRequest,servletResponse);}
}
- 在启动类中添加 @ServletComponentScan
org.springframework.boot.web.servlet.ServletComponentScan;
实现登录校验
@WebFilter(urlPatterns = "/*")
public class FilterDemo implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// 1. 获取请求头HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;String url=request.getRequestURI();//2. 是登录请求直接放行if (url.contains("/login")) {filterChain.doFilter(servletRequest, servletResponse);System.out.println("登录操作合法");return;}//3. 获取请求头的令牌String jwt=request.getHeader("token");// 4.判断令牌是否存在,不存在返回错误if (!StringUtils.hasLength(jwt)) {//没有令牌 返回错误Result result=new Result(0,"NOT_LOGIN",null);// 手动转化 对象 --》json 阿里巴巴 fastjsonString notlogin= JSONObject.toJSONString(result);response.getWriter().write(notlogin);return;}//5.解析token,解析失败返回错误结果try {JwtUtils.parseJWT(jwt);} catch (Exception e) {Result result=new Result(0,"NOT_LOGIN",null);String notlogin= JSONObject.toJSONString(result);response.getWriter().write(notlogin);return;}//6. 放行filterChain.doFilter(servletRequest,servletResponse);}
}
拦截器 Interceptor
概念:是一种动态拦截方法调用的机制,类似于过滤器。Spring 框架中提供。
快速使用
1.定义拦截器,实现 HandlerInterfaceptor 接口
@Component //交给IOC容器管理
public class LoginInterceptor implements HandlerInterceptor {@Override //目标资源方法 运行前运行, 返回 true 放行 false,不放行public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {return HandlerInterceptor.super.preHandle(request, response, handler);}@Override // 运行后进行public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);}@Override // 最后运行public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {HandlerInterceptor.super.afterCompletion(request, response, handler, ex);}
}
- 定义配置类
拦截路径:
拦截路径 | 含义 |
---|---|
/* | 一级路径 |
/** | 任意路径 |
/depts/* | depts 下的一级路径 |
/depts/* | depts 下的任意级路径 |
.excludePathPatterns(“/login”) 不需要拦截的资源
@Configuration //配置类注解
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginInterceptor).addPathPatterns("/**");}
}
实现登录校验
public class LoginInterceptor implements HandlerInterceptor {@Override //目标资源方法 运行前运行, 返回 true 放行 false,不放行public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String token=request.getHeader("token");if (!StringUtils.hasLength(token)) {//没有令牌 返回错误Result result=new Result(0,"NOT_LOGIN",null);// 手动转化 对象 --》json 阿里巴巴 fastjsonString notlogin= JSONObject.toJSONString(result);response.getWriter().write(notlogin);return false;}try {JwtUtils.parseJWT(token);}catch (Exception e){String notlogin=JSONObject.toJSONString(new Result(0,"NOT_LOGIN",null));response.getWriter().write(notlogin);return false;}return true;}
}