重定向后 Cookie 消失

Posted

技术标签:

【中文标题】重定向后 Cookie 消失【英文标题】:Cookies disappear after redirect 【发布时间】:2019-06-10 10:09:12 【问题描述】:

我有:

1) 具有自己的域的客户端应用程序:http://client.com

2) 具有单独域的服务器端应用程序:http://server.com

现在,

场景是:

1) 在浏览器中打开http://client.com/home,会显示一个html页面。

2) http://client.com/home 重定向到 http://server.com/login

3) http://server.com/login 存储一个 cookie 'auth' 并向 http://client.com/welcome 发送重定向指令

回复:

访问控制允许来源:*

连接:保持活动

内容长度:104

内容类型:文本/html;字符集=utf-8

日期:格林威治标准时间 2019 年 1 月 16 日,星期三 10:47:11

位置:http://client.com/welcome

设置-Cookie: auth=1479da80-197c-11e9-ba74-59606594e2fb;路径=/

变化:接受

X-Powered-By: Express

4) 浏览器收到响应,其中包含 cookie 'auth'

5) 浏览器将自身重定向到http://client.com/welcome

6) 'auth' cookie 被发送到http://client.com/welcome

请求:

Cookie:auth=1479da80-197c-11e9-ba74-59606594e2fb

7) http://client.com/welcome 返回 HTML 但不返回 cookie 'auth'

8) http://client.com/welcome 向 http://server.com/data 发出 AJAX 请求(启用 CORS),但未发送 cookie 'auth'

9) http://server.com/data 无法识别用户,因为没有 cookie

客户端是一个由 Node.js 托管的 Angular 应用

编辑:

按照建议,我已添加到 server.com 的响应中:

访问控制允许凭据:true

但没有任何改变。

相关客户端代码:

const headerOptions = new HttpHeaders(
      'Content-Type': 'application/json', 'withCredentials': 'true', 'Access-Control-Allow-Origin': 'true', 'Access-Control-Allow-Credentials': 'true'
    );

this.httpClient.get<any>(this.baseUrl + "data",  headers: headerOptions ).subscribe((res) => 

【问题讨论】:

6) 'auth' cookie is sent to http://client.com/welcome 必须是 Set-Cookie: ... 才能以 Cookie 的形式返回响应。能否贴出完整流程的请求/响应标头? @marekful - 完成 请详细说明第 3 步。 server.com 究竟是如何设置 cookie 的。显示完整的标题。 @Styx - 我已经更新了问题 【参考方案1】:

在将 ajax 请求发送到 http://server.com 时,您应该使用 withCredentials 选项,并且您的 server.com 应该将 Access-Control-Allow-Credentials 设置为 true。

Example code in Node.JS server:

var cors = require('cors');
var corsOptions = 
    origin: '*',
    credentials: true ;

app.use(cors(corsOptions));

更多信息在这里:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials

Example code in Angular.JS client
import RequestOptions, Request, RequestMethod from '@angular/http';

const options = new RequestOptions(
  method: RequestMethod.Post,
  url: 'https://google.com',
  withCredentials: true
);

更多信息在这里:https://angular.io/api/http/RequestOptions

也看看这个:https://github.com/angular/angular/issues/24283 - 看起来某个特定版本的 Angular 有这个标志的问题,所以除非你使用的是更新的版本,否则你可能会需要明确设置标头。

这样做的原因是,除非服务器明确告诉客户端“我将接受另一个域传递的 cookie(以前在我的域上设置)” - 接受 cookie 将是安全问题。 更多:https://en.wikipedia.org/wiki/Cross-site_request_forgery

【讨论】:

我已经更新了问题。我使用 Angular 的 7.1 版。这是一个好版本吗? 您的 cookie 设置为安全吗?你在用 https 吗? 不,我使用的是 http 您更新的代码包含 withCredentials 作为标头。这是一个添加标头的请求选项。请问可以正确使用吗? (查看我提供的代码示例) 还要确保您的浏览器已设置为设置第三方 cookie【参考方案2】:

来自 Access-Control-Allow-Origin 规范: 对于没有凭据的请求,可以指定字面值“”,作为通配符;*

尝试将特定域添加到Access-Control-Allow-Origin 字段。

我认为您应该在 angular angular 应用程序中使用代理。欲了解更多信息,请查看此链接:https://github.com/angular/angular-cli/blob/master/docs/documentation/stories/proxy.md

【讨论】:

【参考方案3】:

您对正在发生的事情的描述似乎不正确。

http://server.com/login 存储一个 cookie 'auth' 并向http://client.com/welcome 发送重定向指令 'auth' cookie 被发送到http://client.com/welcome

这不是(或至少不应该是)正在发生的事情。当浏览器请求http://server.com/login 并在响应中返回Set-Cookie 标头时,cookie 被设置并限制在server.com 域中,即使响应是重定向。如果您看到发送到 client.com 的 'auth' cookie,那么这是 client.com 之前设置的 cookie。

不管怎样,看来你真正关心的是

http://client.com/welcome 向 http://server.com/data 发出 AJAX 请求(已启用 CORS),但未发送 cookie 'auth'

发生这种情况的原因有很多。

CORS。您提到它启用了 CORS,但为了其他人阅读本文,您必须在 server.com 上设置以下 CORS 标头 Access-Control-Allow-Origin: http://client.com Access-Control-Allow-Credentials: true 请注意,当您发送凭据时,您无法避免使用通配符作为Access-Control-Allow-Origin。另请注意,来源必须完全匹配,包括方案(http 或 https)。在实践中,服务器通常会读取请求的Origin 标头,对照白名单检查,如果允许,将请求中的Origin 标头值复制到响应中的Access-Control-Allow-Origin 标头。 您必须在 XHR 请求中设置 xhr.withCredentials = true。 (详情请参阅MDN。)

然后,在您完成所有这些之后,您还有另一个障碍。因为您在client.com 上并尝试向server.com 发送cookie,所以server.com cookie 被视为“第三方”cookie。 AFAIK 所有主要浏览器都有一个设置来阻止第三方 cookie 以保护隐私,因为它们最常被跟踪器用于收集营销数据以进行广告。我相信他们中的大多数默认情况下会阻止第三方 cookie,但我不确定。可以肯定,很多人已将浏览器设置为阻止第三方 cookie。

因此,您必须告诉访问者将浏览器配置为允许来自 server.com 的第三方 cookie。

顺便说一句,在重定向到不同域时设置 cookie 是不安全的。虽然 AFAIK 规范允许这样做,但浏览器支持存在问题。例如,请参阅此Chrome bug。

【讨论】:

谢谢。在我看到您的答案之前,我实际上设法通过 Mavi Domates 和我自己进行的其他研究的线索解决了这个问题。所以我决定将赏金授予 Mavi,但我接受了你的回答,因为它更准确。

以上是关于重定向后 Cookie 消失的主要内容,如果未能解决你的问题,请参考以下文章

易语言怎么获取重定向网址的协议头内的Set-Cookie?

重定向后浏览器不会从带有 www 的域发送 cookie

使用快递设置cookie后如何重定向url?

React:重定向到子域时保留 cookie

从浏览器中删除应用程序 cookie 后调用重定向失败,提示 cors 错误

03 重定向,请求转发,cookie,session