青橘子的服务端 - springboot之跨域错误和session跨域共享

96
Godya
2017.11.15 21:50* 字数 133

一 场景

在book.qjuzi.com域,用Ajax 请求api.qjuzi.com/getSession。

访问页面

# https://api.qjuzi.com/user.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
    <script>
        $(function () {
            $.ajax({
                url: "http://api.qjuzi.com/getSession",
                xhrFields: {
                    withCredentials: true
                },
                success: function( result ) {
                    $( "#session" ).html( "session: <strong>" + result + "</strong>" );
                }
            });
        });
    </script>
</head>
<body>
<div id="session">none</div>
</body>
</html>

默认配置下返回跨域错误

GET http://api.qjuzi.com/getSession 403 ()
Failed to load http://api.qjuzi.com/getSession: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://book.qjuzi.com' is therefore not allowed access. The response had HTTP status code 403.

二 解决

过程一

配置Spring CorsConfiguration来解决跨域资源共享问题。

@Configuration
public class CorsConfig {
    private static String[] originsVal = new String[]{
            "qjuzi.com",
            "local.qjuzi.com",
            "local1.qjuzi.com",
            "localhost"
    };

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        addAllowedOrigins(corsConfiguration); // 1
        corsConfiguration.addAllowedHeader("*"); // 2
        corsConfiguration.addAllowedMethod("*"); // 3
        // corsConfiguration.setAllowCredentials(true); // 跨域session共享
        source.registerCorsConfiguration("/**", corsConfiguration); // 4
        return new CorsFilter(source);
    }

    private void addAllowedOrigins(CorsConfiguration corsConfiguration) {
        for (String origin : originsVal) {
            corsConfiguration.addAllowedOrigin("http://" + origin);
            corsConfiguration.addAllowedOrigin("https://" + origin);
        }
    }
}

请求成功,但是多次请求返回的sessionId不一致。

1:session: b8013b56-2727-4f0d-b116-e8c1c2715ecf
2:session: abda28fc-0b49-47fb-b6d8-b050e78f07d5
3:session: 1387c14f-00f7-4518-8871-dfcf752bba52
4:session: ea9a0fcd-55d0-4aac-984a-dce279779c53

过程二

解决session跨域共享问题。

# 在CorsConfiguration 设置AllowCredentials属性。
corsConfiguration.setAllowCredentials(true);  // 默认不支持User Credentials

# 在ajax的参数xhrFields里,添加 withCredentials: true
xhrFields: {
    withCredentials: true
}

成功返回同样的sessionId。

1: session: 31623391-02f1-457a-b491-89c379c3f951
2: session: 31623391-02f1-457a-b491-89c379c3f951
3: session: 31623391-02f1-457a-b491-89c379c3f951
4: session: 31623391-02f1-457a-b491-89c379c3f951

参考链接

  1. CORS support in Spring Framework
  2. Access-Control-Allow-Credentials
  3. 跨域资源共享 CORS 详解 - 阮一峰 这博客对Credentials的解释更好理解
青橘子的开发记录
Web note ad 1