接上篇--JWT令牌
jwt令牌相当于成功登录的标记,统一校验jwt令牌,即登录成功的标记。第一种方法即这篇的过滤器Filter。
Filter概述
它是JavaWeb三大组件(Servlet、Filter、Listener)之一,Listener指的是监听器。Filter之外的其他两个现在已经很少使用了。
作用:将对资源的请求拦截下来,我的理解就是在请求资源之前先判断一下这个请求是否具备一些条件,就好比用户是否登陆了,只有登陆了才可以访问内部资源。如果没有过滤器的话,我们就需要在每一个接口都编写登录校验的接口,而这部分逻辑功能一样,就可以借助一个过滤器统一处理,如果没有登录,则直接在过滤器中响应错误处理。
用途:常用于登录校验、统一编码处理、敏感字符处理等。
Filter接口
如下图所示:Filter接口中有三个方法,但是我们一般只需要实现doFilter方法即可。init时初始化方法,只调用一次;doFilter拦截到请求便会调用,会调用多次;destory销毁方法,也只调用一次。
登录校验Filter
结合jwt令牌,在访问资源时,我们只需要判断请求体中是否有携带jwt令牌,就可以决定是否需要过滤本次请求,我们需要自己创建一个filter类,并且在其中实现Filter接口。
实现思路:
1.获取请求路径url;
2.如果是登录请求则放行;
3.其他url,获取token中的jwt令牌(因为这个项目中,生成的jwt令牌会存放到请求头中的token中,视情况而定哈);
4.jwt为空,返回错误数据(该项目 要求返回NOT_LOGIN信息);
5.不为空,则解析jwt,判断其是否有效;
6.解析出错,则返回错误;(因为jwt令牌只要不正确就会编译错误,所以可以用一个try catch来捕获该异常)
7.解析正确,放行。
import com.alibaba.fastjson.JSONObject;
import com.itheima.pojo.Result;
import com.itheima.utils.JwtUtils;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import java.io.IOException;
@Slf4j
@WebFilter(urlPatterns = "/*")//代表拦截的是所有路径请求
public class DemoFilter implements Filter {
@Override//每次拦截请求都会调用
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
// 获取url 由于请求参数是servetRequest 需要把它强转为HttpServletRequest才可以获取到url response同理
HttpServletResponse response=(HttpServletResponse)servletResponse;
HttpServletRequest request=(HttpServletRequest)servletRequest;
String url=request.getRequestURL().toString();
// 登录操作 直接放行
if(url.contains("login")){
// 放行 调用filterChain方法实现放行
filterChain.doFilter(servletRequest,servletResponse);
// 放行之后 便可继续执行登录操作 也不需要再执行下面的逻辑了 return即可
return;
}
// 其他url 获取请求头中的token(即jwt令牌)
String jwt=request.getHeader("token");
if(!StringUtils.hasLength(jwt)){
// 如果jwt为空 返回错误信息
Result error=Result.error("NOT_LOGIN");
// 将字符串转换为json对象
String notLogin=JSONObject.toJSONString(error);
// 反应给浏览器
response.getWriter().write(notLogin);
return;
}
// 令牌不为空 解析其是否有效
try {
JwtUtils.parseJWT(jwt);
} catch (Exception e) {
// 出错了 解析;令牌失败 返回错误结果
e.printStackTrace();
log.info("解析令牌失败");
Result error=Result.error("NOT_LOGIN");
// 将字符串转换为json对象 因为过滤器中不会像controller层中将返回值自动转换成json数据
// 这里需要借助阿里巴巴的fastJSON工具包 来转换json 需要引入依赖 代码在下一个代码
String notLogin=JSONObject.toJSONString(error);
// 反应给浏览器
response.getWriter().write(notLogin);
return;
}
// 放行
filterChain.doFilter(request,response);
}
}
阿里巴巴fastJSON依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.0</version>
</dependency>
到这里就结束了 麻烦大家见谅