前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot2.0之CORS跨域配置并保持登录

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

作者头像
用户6182664
发布2020-05-07 15:50:31
1.4K0
发布2020-05-07 15:50:31
举报

1.问题描述

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

比如:

代码语言:javascript
复制
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允许跨域访问。

代码语言:javascript
复制
@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项目中加入如上配置即可,允许所有请求的、所有头、所有方法、所有原始链接跨域访问,当然也可以配置指定的信息跨域访问,这里配置所有。下面我们再试试请求效果。

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

代码语言:javascript
复制
{
    "data":{
        "pass":"admin123",
        "loginName":"admin"
    },
    "message":"操作成功!",
    "resultCode":"00000"
}

3.允许携带Cookies

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

登录请求:

代码语言:javascript
复制
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

获取列表请求:

代码语言:javascript
复制
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就可以解决问题了。

前端配置:

代码语言:javascript
复制
//创建实例
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

代码语言:javascript
复制
registry.addMapping("/**")
  .allowedHeaders("*")
  .allowedMethods("*")
  .allowedOrigins("*")
  .allowCredentials(true);// 允许跨域带上cookies

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

4.完整配置

SpringBoot后端:

代码语言:javascript
复制
@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)配置:

代码语言:javascript
复制
const instance = axios.create({
  baseURL: 'http://127.0.0.1:8085',
  timeout: 10000,
  withCredentials: true // 运行跨域带上cookies
});
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java程序员那些事 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.问题描述
  • 2.配置CORS允许跨域访问。
  • 3.允许携带Cookies
  • 4.完整配置
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档