Cookie在重定向后消失

时间:2019-01-16 10:30:20

标签: node.js angular http redirect cookies

我有:

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

     

Content-Type:文本/ html; charset = utf-8

     

日期:2019年1月16日星期三10:47:11 GMT

     

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

     

Set-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”

enter image description here

enter image description here

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

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

客户端是由Node.js托管的有角度的应用程序

编辑:

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

  

Access-Control-Allow-Credentials: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) => {

3 个答案:

答案 0 :(得分:3)

将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

答案 1 :(得分:1)

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

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

无论如何,看来您真正关心的是

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

  • 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标头值从请求复制到{{1} }标题中。
  • 您必须在XHR请求中设置Access-Control-Allow-Origin。 (有关更多详细信息,请参见MDN。)

然后,在完成所有这些操作之后,您便会遇到另一个障碍。因为您在xhr.withCredentials = true上并试图将cookie发送到client.com,所以server.com cookie被视为“第三方” cookie。 AFAIK所有主要的浏览器都有一个设置,可以阻止第三方Cookie的隐私,因为跟踪器最常使用它们来收集广告的营销数据。我相信大多数默认情况下都会阻止第三方Cookie,但是我不确定。当然,很多人都将其浏览器设置为阻止第三方Cookie。

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

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

答案 2 :(得分:0)

根据“访问控制允许来源”规范: 对于没有凭据的请求,可以将字面值“ ”指定为通配符; *

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

我认为您应该在有角度的角度应用中使用代理。有关更多信息,请检查以下链接:https://github.com/angular/angular-cli/blob/master/docs/documentation/stories/proxy.md