springboot2.x Spring Security Vue-resource跨域问题解决

原因:最近在将一个项目修改为前后端分离中,前端使用Vue 开发碰到跨域问题,这里记录一下。

服务器端修改

1、在配置类中设置 CorsFilter,新建CorsConfig

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 CorsConfig{

	@Bean
	public CorsFilter corsFilter() {
		final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
		final CorsConfiguration config = new CorsConfiguration();
		// 允许cookies跨域
		config.setAllowCredentials(true);
		// 允许向该服务器提交请求的URI,*表示全部允许。。这里尽量限制来源域,比如http://xxxx:8080
		// ,以降低安全风险。。
		config.addAllowedOrigin("*");
		// 允许访问的头信息,*表示全部
		config.addAllowedHeader("*");
		// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了
		config.setMaxAge(18000L);
		// 允许提交请求的方法,*表示全部允许,也可以单独设置GET、PUT等
		config.addAllowedMethod("*");

		/*
		 * config.addAllowedMethod("HEAD"); config.addAllowedMethod("GET");//
		 * 允许Get的请求方法 config.addAllowedMethod("PUT");
		 * config.addAllowedMethod("POST"); config.addAllowedMethod("DELETE");
		 * config.addAllowedMethod("PATCH");
		 */
		source.registerCorsConfiguration("/**", config);
		return new CorsFilter(source);
	}
    
}

2、修改 Spring Security配置,加上cors()来开启跨域以及requestMatchers(CorsUtils::isPreFlightRequest).permitAll()来处理跨域请求中的preflight请求。

	//开启跨域 cors()
	http.cors().
        and().csrf().disable().
        authorizeRequests().
        //处理跨域请求中的Preflight请求
        requestMatchers(CorsUtils::isPreFlightRequest).permitAll()

注:前两步服务器端就已经开启跨域访问了,但是在实际测试中发现,前端访问session一直会发生变化,翻了大量文章后发现spring-session 2.x 中 Cookie里面居然引入了SameSite,他默认值是 Lax。
  SameSite Cookie 是用来防止CSRF攻击,它有两个值:Strict、Lax
SameSite = Strict:
  意为严格模式,表明这个cookie在任何情况下都不可能作为第三方cookie;
SameSite = Lax:
  意为宽松模式,在get请求是可以作为第三方cookie,但是不能携带cookie进行跨域post访问(这就很蛋疼了,我们那个校验接口就是POST请求);
总结:
  前端请求到后台,每次session都不一样,每次都是新的会话,导致获取不到用户信息,添加配置取消仅限同一站点设置。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;

@Configuration
public class SpringSessionConfig {

	@Bean
    public CookieSerializer httpSessionIdResolver() {
        DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
        // 取消仅限同一站点设置
        cookieSerializer.setSameSite(null);
        return cookieSerializer;
    }
}

前端修改

Vue在公共js中添加统一配置

使用Vue.resource发送请求时配置如下:
Vue.http.options.xhr = { withCredentials: true };
Vue.http.interceptors.push((request, next) => {
	request.credentials = true
	next()
})

其他工具配置,可以参考如下配置,未测试;

使用Vue.axios发送请求时配置如下:
axios.defaults.withCredentials = true;

jquery请求带上  xhrFields: {withCredentials: true}, crossDomain: true;
$.ajax({
    type: "post",
    url: "",
    xhrFields: {withCredentials: true},
    crossDomain: true,
    data: {username:$("#username").val()},
    dataType: "json",
    success: function(data){ }
});

参考:
https://www.cnblogs.com/zimublog/p/10786110.html
https://blog.csdn.net/qq_17555933/article/details/92017890
https://www.cnblogs.com/yuarvin/p/10923280.html

你可能感兴趣的:(Java)