在springboot项目中使用Filter进行登录验证

步骤:

  1. 获取请求;
  2. 过滤器拦截请求,然后判断是否为login请求,如果是login请求则放行;
  3. 当登录成功,则返回给用户一个token,在下次请求时,需要在请求头中带上token;
  4. 当再次发送请求时,过滤器获取请求头中的token;
  5. 拦截请求之后,去判断token是否存在,如果不存在返回错误结果;
  6. 如果token存在,则解析token,如果解析失败,返回错误结果;
  7. 解析成功,放行;

过滤器代码

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是否有效,如果有效则可以正常发送请求,否则会返回请先登录提示信息

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值