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

發佈了29 篇原創文章 · 獲贊 15 · 訪問量 36萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章