解决Axios跨域请求时session不一致

解决Axios跨域请求时session不一致
强烈推介IDEA2020.2破解激活,IntelliJ IDEA 注册码,2020.2 IDEA 激活码

1、原因

这个问题的产生关系到会话保持的原理:当浏览器第一次请求服务器时,服务器会为其创建一个session对象,每个session对象有一个自己的唯一id作为自己的标识。服务器为了判断下次请求的是不是同一个浏览器,会把这个sessionId放到cookie中,以cookie的形式返回给浏览器,并暂时存储在浏览器中。这样,只要浏览器不关闭,再去访问服务器时,就会自动带上这个sessionId,服务器再次接收请求时,就会去获取这个sessionId,并与服务器内存中存在的sessionId比对,验证通过就说明这个用户之前访问过,不用为其重新分配新的session对象,就达到了会话的保持。如果以上理解不了的请先自行查阅什么是session和cookie。

所以维持会话的一个关键点其实是携带了sessionId的这个cookie。出现了session不一致的问题,那多半就是跨域请求时没有携带cookie,或者服务器不允许你携带cookie~

根据线索去查阅资料后得知:XMLHttpRequest 存在一个名为withCredentials的属性,该属性默认值为false,在发送同源请求时该属性不起作用,但在作跨域请求时,它的作用就非常大了:
true:在跨域请求时,会携带用户凭证,也就是cookie;
false:在跨域请求时,不会携带用户凭证,并且返回的response里也会忽略cookie。

2.解决方法

锁定了问题的原因,问题自然也就迎刃而解了:

1.设置前端请求的withCredentials属性为true,让其请求时携带cookie;
在axios请求时携带该属性:

this.$axios.get('/api/test',{
   withCredentials : true}).then((res)=>{
   
        console.log(res)
      })

或者在main.js中作全局的配置,一劳永逸~

import Vue from 'vue';
import axios from 'axios';
//请求默认地址
axios.defaults.baseURL = "http://127.0.0.1:8081/";
//请求超时时间
axios.defaults.timeout = 10000;
//post请求头
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
//设置cross跨域 并设置访问权限 允许跨域携带cookie信息
axios.defaults.withCredentials=true;

2.设置后台的withCredentials属性为true,让其允许前端携带cookie请求,并在响应时也携带cookie。

在springboot构建的项目中,如果用的@CrossOrigin注解,为其加上allowCredentials参数,作局部的处理:@CrossOrigin(allowCredentials="true")(在@CrossOrigin源码中默认为false)。

或者使用拦截器或过滤器作全局的配置:

拦截器:

package com.example.pahms.Inteceptor;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class CORSInterceptor implements HandlerInterceptor {
   
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
   
        response.setHeader("Access-Control-Expose-Headers", "token");// 服务器 headers 白名单,可以让客户端进行访问操作的属性
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        return true;
    }

}

过滤器:

package com.example.pahms.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class GlobalCorsConfig {
   

    @Bean
    public CorsFilter corsFilter() {
   
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOrigin("*");
        config.setAllowCredentials(true);
        config.addAllowedMethod("*");
        config.addAllowedHeader("*");
        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);
        return new CorsFilter(configSource);
    }

}
本文来源MrKorbin,由架构君转载发布,观点不代表Java架构师必看的立场,转载请标明来源出处:https://javajgs.com/archives/25307

发表评论