前后端分离--跨域问题--Cookie SameSite(一)

一、SameSite Cookie 简介

SameSite-cookies是一种机制,用于定义cookie如何跨域发送。这是谷歌开发的一种安全机制,并且现在在最新版本(Chrome Dev 51.0.2704.4)中已经开始实行了。SameSite-cookies的目的是尝试阻止CSRF(Cross-site request forgery 跨站请求伪造)以及XSSI(Cross Site Script Inclusion (XSSI) 跨站脚本包含)攻击。

二、语法

语法是SameSite=, 例如SameSite=Lax

  1. Strict
    Strict是最严格的防护,有能力阻止所有CSRF攻击。然而,它的用户友好性太差,因为它可能会将所有GET请求进行CSRF防护处理。
    例如:一个用户在reddit.com点击了一个链接(GET请求),这个链接是到facebook.com的,而假如facebook.com使用了Samesite-cookies并且将值设置为了Strict,那么用户将不能登陆Facebook.com,因为在Strict情况下,浏览器不允许将cookie从A域发送到B域。
  2. Lax
    Lax(relax的缩写?)属性只会在使用危险HTTP方法发送跨域cookie的时候进行阻止,例如POST方式。
    例1:一个用户在reddit.com点击了一个链接(GET请求),这个链接是到facebook.com的,而假如facebook.com使用了Samesite-cookies并且将值设置为了Lax,那么用户可以正常登录facebok.com,因为浏览器允许将cookie从A域发送到B域。
    例2:一个用户在reddit.com提交了一个表单(POST请求),这个表单是提交到facebook.com的,而假如facebook.com使用了Samesite-cookies并且将值设置为了Lax,那么用户将不能正常登陆Facebook.com,因为浏览器不允许使用POST方式将cookie从A域发送到B域。

三、SpringWeb

spring web 最新版默认生成为SameSite=Lax,奇怪的是用spring data Session redis 后 cookie新增了 SameSite这个字段,所以不能携带cookie进行跨域post访问,文档上也不表明什么时候开始的,坑的是默认为Lax也不能设置,遂现在将web版本降级。
因为服务端返回给客户端的set-cookie中带有samesite=lax,这就是问题的根源,它表示不能携带cookie进行跨域post访问,然而我们是需要携带cookie的。
解决办法:

  1. 后端配置
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
    @Bean
    public CookieSerializer httpSessionIdResolver() {
        DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
        // 取消仅限同一站点设置
        cookieSerializer.setSameSite(null);
        return cookieSerializer;
    }

并设置:

response.setHeader("Access-Control-Allow-Credentials", "true");
或
    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
//        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedOrigin("http://localhost:8088");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.setAllowCredentials(true);    // true代表允许携带cookie
        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        // “*”代表全部。”**”代表适配所有接口。
        source.registerCorsConfiguration("/**", buildConfig());
        return new CorsFilter(source);
    }
  1. 前端ajax请求:
    添加:
xhrFields: {
    withCredentials: true
}

你可能感兴趣的:(前后端分离--跨域问题--Cookie SameSite(一))