CORS 跨域中的 Cookie处理

CORS 跨域中的 Cookie

概述

​ 基于安全方面的考虑,在浏览器中无法获取跨域的 Cookie 这一点时永远不变的。但是我们处理跨域请求时有可能会遇到这样的情况:一个网页与域为bbb.cn的服务器正常发送请求和接收响应,同时这个网页也需要跨域访问aaa.cn服务器。

​ 众所周知,浏览器会在准备发送的请求中附上所有符合要求的Cookie,故在上面的情况中浏览器会自动处理网页与域为bbb.cn的服务器之间的 Cookie;但是在 CORS 跨域中,浏览器并不会自动发送 Cookie,也就是说,浏览器不会处理网页与aaa.cn服务器之间的 Cookie。

配置说明

要想浏览器处理 CORS 跨域中的 Cookie 只需要分别在网页以及服务端作出一点点改变:

  1. 网页端中,对于跨域的 XMLHttpRequest 请求,需要设置withCredentials 属性为 true。

    var xhr = new XMLHttpRequest();
    xhr.open("GET", "http://aaa.cn/localserver/api/corsTest");
    xhr.withCredentials = true; // 设置跨域 Cookie
    xhr.send();
    
  2. 同时服务端的响应中必须携带 Access-Control-Allow-Credentials: true 首部。如果服务端的响应中未携带Access-Control-Allow-Credentials: true 首部,浏览器将不会把响应的内容返回给发送者。

要想设置和获取跨域 Cookie,上面提到的两点缺一不可。另外有一点需要注意的是:规范中提到,如果 XMLHttpRequest 请求设置了withCredentials 属性,那么服务器不得设置 Access-Control-Allow-Origin的值为* ,否则浏览器将会抛出The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' 错误。

在基于 Filter 的 CORS 跨域中应用 Cookie

​ 基于 Filter 的 CORS 跨域实现实际上就是手动在响应中添加 CORS 要求的响应首部字段。一个简单 Filter 实现如下:

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    System.out.println("work");
    HttpServletResponse response = (HttpServletResponse) servletResponse;
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
    filterChain.doFilter(servletRequest, servletResponse);
}

但是正如上面提到的:如果 XMLHttpRequest 请求设置了withCredentials 属性,那么服务器不得设置 Access-Control-Allow-Origin的值为* ,所以我们需要处理Access-Control-Allow-Origin 首部字段的值,否则将会得到以下的错误:

下面提供一种处理Access-Control-Allow-Origin 首部字段值的方法,我们可以根据请求的域来动态的设置:

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    HttpServletResponse response = (HttpServletResponse) servletResponse;
    String origin = request.getHeader("origin");// 获取源站
    response.setHeader("Access-Control-Allow-Origin", origin);
    response.setHeader("Access-Control-Allow-Methods", "POST, GET");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
    filterChain.doFilter(servletRequest, servletResponse);
}

最后,在 Java Web 应用程序中获取和设置 Cookie 方法与普通的没有区别。

Cookie cookie = new Cookie("test", "value");
response.addCookie(cookie);

Cookie[] cookies = request.getCookies();

在基于@CorssOrigin 注解的 CORS 跨域中应用 Cookie

​ 在使用 Spring 提供的 CORS 支持的 @CorssOrigin 注解时,我们只需要在网页端设置跨域 XMLHttpRequest 请求的 withCredentials 属性就可以正常设置和获取跨域 Cookie。这是因为 Spring 的@CorssOrigin 注解默认情况下已经为我们设置响应中的 Access-Control-Allow-Credentials: true 首部,同时也会根据实际接收到的请求的源站设置 Access-Control-Allow-Origin首部。

​ 在 Spring MVC 中配置使用 CORS跨域的方法我已经在前面的文章中介绍过,详细的可以阅读文章Spring MVC 实现 CORS 跨域。 使用@CorssOrigin 注解后服务器设置 Cookie 的响应首部如下图所示:

​ 最后,跟上面一样,在 Java Web 应用程序中获取和设置 Cookie 方法与普通的没有区别。



作者:ken_ljq
链接:https://www.jianshu.com/p/13d53acc124f
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值