Springboot 如何实现filter拦截token验证和跨域

针对您的问题,我来为您详细讲解Spring Boot如何实现filter拦截token验证和跨域。

一、使用Filter拦截Token验证

1. 引入相关依赖

在pom.xml文件中引入以下相关依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.9.1</version>
    </dependency>
</dependencies>

2. 编写TokenFilter

在项目中新建TokenFilter.java文件,继承OncePerRequestFilter类,并重写doFilterInternal方法。在该方法中,我们可以对请求头中的Token进行验证。

import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class TokenFilter extends OncePerRequestFilter {

    @Value("${jwt.secret}")
    private String secret;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String token = request.getHeader("Authorization");
        if(StringUtils.isEmpty(token) || !token.startsWith("Bearer ")){
            filterChain.doFilter(request, response);
            return;
        }

        try {
            Claims claims = Jwts.parser()
                        .setSigningKey(secret)
                        .parseClaimsJws(token.replace("Bearer ", ""))
                        .getBody();
            request.setAttribute("claims", claims);
        } catch (SignatureException e) {
              response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid Token!");
              return;
        }
        filterChain.doFilter(request, response);
    }
}

3. 配置TokenFilter

在Spring Boot中使用@WebFilter注解进行配置。在项目启动时,会自动加载该Filter进行处理。

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.RequestContextFilter;

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean tokenFilter(){
        FilterRegistrationBean<TokenFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new TokenFilter());
        registrationBean.addUrlPatterns("/*");
        registrationBean.setName("TokenFilter");
        registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return registrationBean;
    }
}

至此,我们就已经完成了使用Filter拦截Token验证的过程。

二、使用Filter实现跨域请求

1. 编写CorsFilter

在项目中新建CorsFilter.java文件,继承OncePerRequestFilter类,并重写doFilterInternal方法。在该方法中,我们可以设置response的header,实现跨域请求。

import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class CorsFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "*");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type,Access-Token");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Expose-Headers", "*");
        if("OPTIONS".equalsIgnoreCase(request.getMethod())){
            response.setStatus(HttpServletResponse.SC_OK);
            return;
        }
        filterChain.doFilter(request, response);
    }
}

2. 配置CorsFilter

同样地,在Spring Boot中使用@WebFilter注解进行配置。在项目启动时,会自动加载该Filter进行处理。

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean corsFilter(){
        FilterRegistrationBean<CorsFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new CorsFilter());
        registrationBean.addUrlPatterns("/*");
        registrationBean.setName("CorsFilter");
        registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return registrationBean;
    }
}

至此,我们就已经完成了使用Filter实现跨域请求的过程。

三、完整的配置文件

最后,如果您需要参考完整的配置文件,可以使用以下代码块进行配置。该配置文件中包含上述两种Filter的配置。

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.RequestContextFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Configuration
public class FilterConfig {

    @Value("${jwt.secret}")
    private String secret;

    @Bean
    public FilterRegistrationBean tokenFilter(){
        FilterRegistrationBean<TokenFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new TokenFilter());
        registrationBean.addUrlPatterns("/*");
        registrationBean.setName("TokenFilter");
        registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return registrationBean;
    }

    @Bean
    public FilterRegistrationBean corsFilter(){
        FilterRegistrationBean<CorsFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new CorsFilter());
        registrationBean.addUrlPatterns("/*");
        registrationBean.setName("CorsFilter");
        registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return registrationBean;
    }

    private class TokenFilter extends OncePerRequestFilter {

        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
            String token = request.getHeader("Authorization");
            if(StringUtils.isEmpty(token) || !token.startsWith("Bearer ")){
                filterChain.doFilter(request, response);
                return;
            }

            try {
                Claims claims = Jwts.parser()
                        .setSigningKey(secret)
                        .parseClaimsJws(token.replace("Bearer ", ""))
                        .getBody();
                request.setAttribute("claims", claims);
            } catch (SignatureException e) {
                response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid Token!");
                return;
            }
            filterChain.doFilter(request, response);
        }
    }

    private class CorsFilter extends OncePerRequestFilter {

        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "*");
            response.setHeader("Access-Control-Allow-Headers", "Content-Type,Access-Token");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Expose-Headers", "*");
            if("OPTIONS".equalsIgnoreCase(request.getMethod())){
                response.setStatus(HttpServletResponse.SC_OK);
                return;
            }
            filterChain.doFilter(request, response);
        }
    }
}

至此,希望我这份攻略可以帮到您。如果还有任何问题,欢迎继续提问。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Springboot 如何实现filter拦截token验证和跨域 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • SpringBoot整合Druid数据源的方法实现

    SpringBoot整合Druid数据源的方法实现,可以分为以下几个步骤: 步骤一:添加Druid和jdbc依赖 在pom.xml文件中,添加以下两个依赖 <!–Druid数据库连接池–> <dependency> <groupId>com.alibaba</groupId> <artifactId&…

    Java 2023年5月20日
    00
  • Lucene单值编码压缩算法源码解析

    Lucene单值编码压缩算法源码解析 算法简介 Lucene单值编码压缩算法是一种占用空间极小、压缩率极高的算法,主要用于Lucene搜索引擎中的索引数据存储。该算法的核心思想是将一个整数序列转化为一个字节数组,最终实现对数据的高效压缩。 算法原理 Lucene单值编码压缩算法采用可变字节长度编码方式,即不同数值的编码长度可能不同。对于一个整数,首先根据它的…

    Java 2023年5月20日
    00
  • Java如何获取字符串单词个数

    要获取一个字符串中的单词个数,可以使用Java的正则表达式和字符串操作。 具体步骤如下: 将字符串按照空格或标点符号进行分割,得到字符串数组(即每个元素为一个单词)。 统计字符串数组的长度,即为单词的个数。 下面是代码实现: public static int getWordCount(String str) { if (str == null || str…

    Java 2023年5月27日
    00
  • Java中easypoi的使用之导入校验

    一、什么是easypoi EasyPoi是一套基于apache poi封装的Java Excel工具,目的是为了简化Excel操作,特别是复杂的不规则的报表格式的导出,同时实现Excel中一些特殊类型的导入导出,如图片、公式等。可以用于做POI导出和POI导入,功能非常强大。 二、导入校验的步骤 2.1 准备工作 首先,我们需要准备一个带有数据的Excel模…

    Java 2023年5月20日
    00
  • Java配置DBeaver的详细步骤

    以下是Java配置DBeaver的详细步骤: 步骤一:下载并安装DBeaver 1.前往DBeaver官网,下载对应操作系统的安装包。例如:Windows系统下载dbeaver-ce-x.y.z-x64-setup.exe。 2.双击exe文件,按照向导提示安装DBeaver。 步骤二:安装MySQL驱动 1.前往MySQL官网,下载对应版本的MySQL C…

    Java 2023年6月1日
    00
  • Spring 框架中注入或替换方法实现

    Sure! Spring 有很多注入或者替换方法的实现方式,其中比较常见的有以下几种方式: 基于 XML 基于 Java Config 基于注解 下面将逐步介绍这几种方式的具体实现方法和示例。 1. 基于 XML 基于 XML 的方式是 Spring 最早期的实现方式,也是应用最广泛的一种方式。在 XML 中,我们可以通过 <bean> 标签配置…

    Java 2023年5月19日
    00
  • Java实现的对称加密算法3DES定义与用法示例

    Java实现的对称加密算法3DES定义与用法示例 1. 什么是3DES 3DES(Triple DES)是一种对称加密算法,常用于数据加密、数字签名等场景。它是DES(Data Encryption Standard)算法的增强版,采取3次DES步骤进行加密,因此也被称为TDEA(Triple Data Encryption Algorithm)。 3DES…

    Java 2023年5月18日
    00
  • 什么是即时编译(AOT)?

    即时编译(AOT)是指在程序运行前将源代码编译成机器码。不同于传统的预编译,AOT编译是在程序运行前进行编译的,可以将程序的执行效率提高。 下面是AOT的完整使用攻略: 1. AOT的原理 AOT编译是将程序源代码在编译时生成机器码。在程序运行时,不需要再进行编译,可以直接运行机器码,从而提高程序的运行效率。 2. AOT的使用方式 AOT编译在不同语言和平…

    Java 2023年5月11日
    00
合作推广
合作推广
分享本页
返回顶部