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

一、问题描述

在项目中使用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;
    }
}

你可能感兴趣的:(Java,Redis,vue.js,前端,javascript)