JWT:
全称:JSON Web Token
定义了一种简洁的、自包含的格式,用于在通信双方以json数据格式安全的传输信息,由于数字签名的存在,这些信息是可靠的。
组成:
Header(头部):(“alg":"HS256","type":"JWT")签名算法和令牌类型
Base64:基于64个可打印字符(A-Z,a-z,0-9,+,/)来表示二进制数据的编码方式
Payload(有效载荷):
携带一些自定义信息,默认信息
Signature(签名):防止Token被篡改,确保安全性。
应用场景:登录认证
JWT令牌的生成和校验
首先引入依赖,
组织名:io.jsonwebtoken
依赖:jjwt
生成JWT用到Jwts.builder()
自带方法:
signWith(SignatureAlgorithm.HS256,"miyao")//签名算法
setClaims(claims)//自定义内容载荷
setExpiration(new Data(System.currentTimeMillis()+让JWT令牌有效的时间))
compact()
注:claim是一个Map类型的数据
解析JWT用到Jwts.parser()
方法:
setSigningKey("miyao")
parseClaimsJws("生成的JWT令牌")
getBody()
可以用Claim来接受第二部分的内容。
JWT校验时使用的签名密钥必须和生成JWT令牌使用的密钥配套。
JWT令牌跟踪会话
令牌生成:登录成功后生成JWT令牌并返回给前端。
将JWT令牌封装在result中返回
一个案例:
if(查询结果不为空){
//可以用登录用户的信息构造一个claims
String jwt = JwtUtils.generateJwt(claims);
return Result.success(jwt)
}else{
return Result.error("用户名或密码错误");
}
过滤器Filter:
javaweb三大组件之一(Servlet\Filter\Listener)
过滤器可以把对资源的请求全部都拦截下来
通用操作:登录校验、统一编码处理、敏感字符处理。
过滤器开发步骤:
1、定义一个类,实现Filter接口,并重写所有方法:(可以给filter单独开一个包)
init() 初始化方法,Web服务器启动后创建Filter调用,只调用一次
doFilter() 拦截请求时,调用该方法
chain.doFilter(request,response);//放行
destroy() 销毁方法,服务器关闭时调用,只调用一次
2、配置Filter:
在Filter类上加@WebFilter注解,配置拦截资源的路径
@WebFilter(urlPattern = "/*")
在springboot启动类上加@ServletComponentScan开启Servlet组件支持。
详细解释(执行流程、拦截路径、过滤器链)
执行流程:放行前逻辑、放行、放行后逻辑
(就是在chain.doFilter(request,response);前后执行的逻辑)
-
放行前逻辑(before chain.doFilter(request, response)):
- 参数处理:对请求参数进行预处理或校验,如解析请求参数、验证参数合法性等。
- 请求处理:对请求进行处理,如记录请求日志、修改请求信息等。
- 鉴权逻辑:进行权限校验,确定请求的访问权限是否符合要求。
- 数据加工:对数据进行预处理,如数据加密、解密等。
- 异常处理:对可能发生的异常进行预处理,如捕获异常并记录日志。
-
放行后逻辑(after chain.doFilter(request, response)):
- 响应处理:对响应进行处理,如记录响应日志、修改响应信息等。
- 数据加工:对响应数据进行处理,如数据加密、解密等。
- 统计信息:统计请求处理的相关信息,如请求处理时间、请求频率等。
- 异常处理:对可能发生的异常进行后续处理,如捕获异常并返回错误信息。
拦截路径:Filter可以根据需求,配置不同的拦截资源路径:
可以进行目录拦截,比如@WebFilter(urlPattern = "/CSDN/*")拦截该目录下的所有资源。
过滤器链:一个WEB应用中可以配置多个过滤器。
过滤器顺序与字符串类名顺序一致。
实际业务:登录校验
登录校验我们需要在过滤器中,完成如下几步。
doFilter的参数:ServletRequest request,ServletResponse response,FilterChain chain
首先要将ServletRequest request,ServletResponse response强转为HTTP类型
1、获取请求url
通过request的getRequestURL方法获取请求路径。
2、判断请求url中是否包含login,如果包含则说明是登录操作,放行
if(url.contains("login")){
chain.doFilter(request,response);
return;
}
3、获取请求头中的token
String jwt = req.getHeader("token");
4、判断令牌是否存在,如果不存在,返回错误结果(未登录)
使用StringUtil工具类的hasLength方法来判断token是否存在
如果不存在返回错误信息:
Result error = Result.error("NOT_LOGIN");
这里我们需要手动将error转换为JSON类型的数据再返回!//使用阿里巴巴的fastJSON
String notLogin = JSONObject.toJSONString(error);
resp.getWriter().write(notLogin);
return;
5、解析token,如果解析失败,返回错误结果(未登录)
使用try-catch语句,利用JwtUtil工具类进行解析6、
Spring框架提供的,用来动态拦截控制器方法的执行
拦截器Interceptor:
拦截器开发步骤:
1、定义拦截器,实现HandlerInterceptor接口,并重写方法(可以给interceptor单独开一个包)
boolen preHandle目标资源方法执行前执行,返回true,放行,返回false,不放行。
postHandle()目标资源方法执行后执行
afterHandle()视图渲染完毕后执行,最后执行
2、配置拦截器
设置一个配置类WebConfig重写WebMvcConfigurer接口,@Configuration
实现addInterceptors方法
registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**");
excludePathPatterns("/login")可以设置除了这个资源以外其他都拦截
拦截器拦截路径与执行流程:
实际业务:登录校验
与过滤器一致。将放行代码改为return true即可。