【Token】使用HandlerInterceptor拦截器解决Vue项目中跨域时预请求问题

29 篇文章 2 订阅

一、问题描述

在项目中使用token取代session实现登录鉴权时,Vue中每次请求都会带有携带token的请求头Authorization ,此时前端会发送两次请求,在跨域请求中,浏览器会首先发送一个预检请求(Preflight Request)来检查服务器是否允许跨域请求。预检请求是一个 OPTIONS 请求,其中包含一个 Access-Control-Request-Headers 头部信息,用于列出实际请求中会包含的请求头。服务器需要正确响应预检请求,并在响应中包含 Access-Control-Allow-Headers 头部信息,以允许实际请求中包含列出的请求头。 如果在预检请求中使用拦截器检查请求头信息,但只有第一次预请求会被拦截,可能是因为您的服务器没有正确响应预检请求。在预检请求中,浏览器会发送一个 Access-Control-Request-Headers 头部信息来列出实际请求中会包含的请求头。如果服务器没有正确响应预检请求,即没有包含 Access-Control-Allow-Headers 头部信息,浏览器就会认为服务器不允许实际请求中包含列出的请求头,从而不会发送实际请求,也就不会触发拦截器。 因此,如果希望拦截器能够检查实际请求中包含的请求头信息,需要确保服务器正确响应预检请求,并在响应中包含 Access-Control-Allow-Headers 头部信息。您可以在 addCorsMappings 方法中使用 allowedHeaders 方法来指定允许跨域请求中包含的请求头。同时,还需要在拦截器中检查请求头信息,并根据需要进行处理。

二、解决

首先需要在配置类中进行跨域配置



/**
 * 将拦截器配置入spring
 */
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    

    /**
     * 解决前端跨域问题
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowCredentials(true)                  // 允许携带cookie
                .allowedHeaders("*") // 允许跨域请求中包含 token 头部信息
                .allowedMethods("*")
                .allowedOrigins("http://localhost:7070");// 跨域地址
    }
}

然后现在我们需要去拦截器里处理预请求问题,以及真实请求到达服务器时的鉴权处理

package com.example.demo.interceptor;

import com.example.demo.component.RedisUtil;
import com.example.demo.component.TokenUtil;
import com.example.demo.model.User;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

/**
 * 对用户登录权限的校验进行统一拦截处理
 */
public class LoginInterceptor implements HandlerInterceptor {


    /**
     * 对用户的访问请求进行统一的登录校验
     * @param request
     * @param response
     * @param handler
     * @return false 拦截请求  true 请求继续
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (request.getMethod().equals("OPTIONS")) { // 如果是预检请求
            String headers = request.getHeader("Access-Control-Request-Headers"); // 获取请求头信息
            if (headers != null && headers.contains("token")) { // 检查请求头信息是否包含 Authorization
                response.setHeader("Access-Control-Allow-Headers", "token"); // 在响应中包含 Access-Control-Allow-Headers 头部信息,允许实际请求中包含 Authorization 请求头
                return true;
            }
        }

        
// 此处做鉴权处理
        return true;
    }
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1886i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值