步骤:
- 获取请求;
- 过滤器拦截请求,然后判断是否为login请求,如果是login请求则放行;
- 当登录成功,则返回给用户一个token,在下次请求时,需要在请求头中带上token;
- 当再次发送请求时,过滤器获取请求头中的token;
- 拦截请求之后,去判断token是否存在,如果不存在返回错误结果;
- 如果token存在,则解析token,如果解析失败,返回错误结果;
- 解析成功,放行;
过滤器代码
package com.fzb.Filter;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.fzb.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import javax.servlet.*;
import javax.servlet.Filter;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* @author by FZB
* @date 2023/7/21
*/
@WebFilter(urlPatterns = "/*")
@Slf4j
public class LoginFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
httpServletResponse.setContentType("application/json;charset=utf-8");
/*
在SpringBoot中,ServletRequest和HttpServletRequest都是Java Web开发中的重要接口。
ServletRequest是Java Web开发中定义的基本请求接口,它提供了获取请求参数、获取请求数据、获取客户端请求信息等方法。
HttpServletRequest是ServletRequest的子类,它添加了一些处理HTTP协议相关的方法,如获取HTTP请求头、获取请求方式、获取会话信息等。
*/
//1.获取请求url
String url = httpServletRequest.getRequestURL().toString();
//打印日志
log.info("获取的请求:{}",url);
//2.判断请求中是否包含login,包含则放行请求
if (url.contains("login")) {
log.info("请求放行,登录成功");
filterChain.doFilter(servletRequest,servletResponse);
return;
}
//3,不是login请求则获取请求头信息
//HttpServletRequest是ServletRequest的子类,它添加了一些处理HTTP协议相关的方法,如获取HTTP请求头、获取请求方式、获取会话信息等。
String jwt = httpServletRequest.getHeader("token");
//4.判断令牌是否存在,如果不存在,返回错误信息
if(!StringUtils.hasLength(jwt)){
log.info("token不存在,返回未登录的信息");
Map map = new HashMap();
map.put("msg","请先登录");
//因为没有在controller层,无法使用@RestController注解,需要自己将返回的数据转为JSON格式;
/**
* httpServletResponse 是一个接口,代表HTTP响应对象,它提供了一些方法来设置HTTP响应的头部信息、状态码、内容类型等。
* getWriter() 是 httpServletResponse 接口的一个方法,它返回一个 PrintWriter 对象,用于将数据写入到响应输出流中。
* write(string) 是 PrintWriter 对象的一个方法,用于将指定的字符串写入到响应输出流中。
*/
String string = JSON.toJSONString(map);
System.out.println(string);
httpServletResponse.getWriter().write(string);
return;
}
//5.解析token如果解析失败,返回错误信息
try {
JwtUtil.parseJWT("itheima", jwt);
} catch (Exception e) {
log.info("解析令牌失败,返回未登录信息");
Map map = new HashMap();
map.put("msg","请先登录");
String string = JSONObject.toJSONString(map);
httpServletResponse.getWriter().write(string);
e.printStackTrace();
return;
}
//登录成功,放行
log.info("验证成功,放行...");
filterChain.doFilter(servletRequest,servletResponse);
}
}
package com.fzb.controller;
import com.fzb.utils.JwtUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author by FZB
* @date 2023/7/20
*/
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/login")
public Map login(String username){
Map claims = new HashMap();
claims.put("username",username);
String jwt = JwtUtil.createJWT("itheima", 1000 * 60 * 60 * 1, claims);
System.out.println(jwt);
Map map = new HashMap();
map.put("msg","登录成功!");
map.put("token",jwt);
return map;
}
@GetMapping("/getUser")
public Map getUser(){
Map map = new HashMap();
map.put("username","李四");
map.put("password","123456");
return map;
}
}
首先发送login请求,过滤器会放行login请求,然后会返回给用户一个token,在用户发送其他请求时,需要在请求头里,携带token,然后过滤器会验证这个token是否有效,如果有效则可以正常发送请求,否则会返回请先登录提示信息