SpringBoot2.0之CORS跨域配置并保持登录

本文主要记录了如何使用SpringBoot2.0配置CORS实现跨域,来解决前(Vue)后(SpringBoot)分离中带来的跨域问题。并实现Session登录后允许携带Cookie来保持登录的状态。

** 主要内容: **
1.问题描述
2.配置跨域
3.允许携带Cookies
4.完整配置

1.问题描述

在前后分离的项目中,前端项目往往和后端项目是分开开发。前端有自己的服务器来访问页面比如http://127.0.0.1:8080,然后通过网络库(Axios)来实现Ajax请求后端服务器http://127.0.0.1:8085来实现数据的展现。

比如:

import axios from 'axios';

//创建实例
const instance = axios.create({
  baseURL: 'http://127.0.0.1:8085',
  timeout: 10000
});

//发起请求
instance.post("/admin/login", Qs.stringify({loginName: admin, pass: 123456}), {
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    }
  });

此时就会报如下错误

Failed to load http://127.0.0.1:8085/admin/login: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8080' is therefore not allowed access.

这就是问题所在,下面我们配置SpringBoot的CORS来实现允许Ajax跨域。

2.配置CORS允许跨域访问。

@Configuration
public class CORSConf {
    private static final Logger LOG = LoggerFactory.getLogger(CorsConfiguration.class);

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                if (LOG.isInfoEnabled()) {
                    LOG.info("初始化 CORSConfiguration 配置");
                }
                registry.addMapping("/**")
                        .allowedHeaders("*")
                        .allowedMethods("*")
                        .allowedOrigins("*");
            }
        };
    }
}

在你的SpringBoot项目中加入如上配置即可,允许所有请求的、所有头、所有方法、所有原始链接跨域访问,当然也可以配置指定的信息跨域访问,这里配置所有。下面我们再试试请求效果。

重启后台服务器,重新请求,不会报错了。

{
    "data":{
        "pass":"admin123",
        "loginName":"admin"
    },
    "message":"操作成功!",
    "resultCode":"00000"
}

3.允许携带Cookies

当服务端使用session来保存登录信息,传统的应用时,只需要登录一次,剩下的访问都不需要登录,因为Cookie里保存了JSESSIONID信息,后台根据JSESSIONID拿到已经登录的Session来判断用户是否需要重新登录。但是前后分离项目里似乎没管用。观察2次请求发现:

登录请求:

Request URL:http://127.0.0.1:8085/admin/login
Request Method:POST
Status Code:200 
Remote Address:127.0.0.1:8085
Referrer Policy:no-referrer-when-downgrade
Response Headers
view source
Access-Control-Allow-Origin:*
Content-Length:112
Content-Type:application/json
Date:Tue, 28 Aug 2018 01:13:29 GMT
Set-Cookie:JSESSIONID=5BAB67B259B9F426A6B4DD51074725F6; Path=/; HttpOnly
Vary:Origin
Vary:Access-Control-Request-Method
Vary:Access-Control-Request-Headers

获取列表请求:

Request URL:http://127.0.0.1:8085/blog/category/list
Request Method:GET
Status Code:200 
Remote Address:127.0.0.1:8085
Referrer Policy:no-referrer-when-downgrade
Response Headers
view source
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:*
Access-Control-Allow-Methods:POST, GET, OPTIONS, DELETE, PUT, HEAD
Access-Control-Allow-Origin:http://127.0.0.1:8080
Content-Type:application/json; =;charset=utf-8
Date:Tue, 28 Aug 2018 01:13:29 GMT
Set-Cookie:JSESSIONID=030E930C2891EFEA0B56A9023AC8EF09; Path=/; HttpOnly
Transfer-Encoding:chunked

可以发现在Set-Cookie:里的JSESSIONID不是一致,那么这就是问题所在了,第二次请求的SESSION不是登录的SESSION,所以导致获取不到登录的用户信息。那么保证2次的JSESSIONID就可以解决问题了。

前端配置:

//创建实例
const instance = axios.create({
  baseURL: 'http://127.0.0.1:8085',
  timeout: 10000,
  withCredentials: true // 允许跨域带上cookies
});

只需要加入withCredentials: true 就可以了

再次请求登录报如下错误:

Failed to load http://127.0.0.1:8085/admin/login: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://127.0.0.1:8080' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

这是因为前端设置了允许携带Cookie,但是后端没设置允许,所以后端也应该设置允许跨域带上cookie

registry.addMapping("/**")
  .allowedHeaders("*")
  .allowedMethods("*")
  .allowedOrigins("*")
  .allowCredentials(true);// 允许跨域带上cookies

这样就完美的解决了跨域请求并保持登录的状态了,可以愉快的开发了。

4.完整配置

SpringBoot后端:

@Configuration
public class CORSConf {
    private static final Logger LOG = LoggerFactory.getLogger(CorsConfiguration.class);

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                if (LOG.isInfoEnabled()) {
                    LOG.info("初始化 CORSConfiguration 配置");
                }
                registry.addMapping("/**")
                        .allowedHeaders("*")
                        .allowedMethods("*")
                        .allowedOrigins("*")
                        .allowCredentials(true);
            }
        };
    }
}

前端(Axios)配置:

const instance = axios.create({
  baseURL: 'http://127.0.0.1:8085',
  timeout: 10000,
  withCredentials: true // 运行跨域带上cookies
});

你可能感兴趣的:(SpringBoot2.0之CORS跨域配置并保持登录)