node.js Angularjs $http 似乎不理解响应中的“Set-Cookie”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19383311/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 15:59:48  来源:igfitidea点击:

Angularjs $http does not seem to understand "Set-Cookie" in the response

node.jsangularjsexpress

提问by Fred Mériot

I have a nodejs express REST api with Passport module for authentication. A login method (GET) returns a cookie in the header. When I call it from Chrome it works fine, my cookie is set in my browser.

我有一个带有用于身份验证的 Passport 模块的 nodejs express REST api。登录方法 (GET) 在标头中返回一个 cookie。当我从 Chrome 调用它时它工作正常,我的 cookie 设置在我的浏览器中。

But if I call it through $http from Angularjs, the cookie is not set.

但是,如果我通过 Angularjs 的 $http 调用它,则不会设置 cookie。

Set-Cookie:connect.sid=s%3Ad7cZf3DSnz-IbLA_eNjQr-YR.R%2FytSJyd9cEhX%2BTBkmAQ6WFcEHAuPJjdXk3oq3YyFfI; Path=/; HttpOnly

As you can see above, the Set-Cookie is present in the header of the http service response.

正如您在上面看到的,Set-Cookie 存在于 http 服务响应的标头中。

Perhaps HttpOnly may be the source of this problem? If yes, how can I change it? Here is my express configuration :

也许 HttpOnly 可能是这个问题的根源?如果是,我该如何更改?这是我的快速配置:

app.configure(function () {
    app.use(allowCrossDomain);
    app.use(express.bodyParser());
    app.use(express.cookieParser())
    app.use(express.session({ secret: 'this is a secret' }));
    app.use(flash());
    //passport init
    app.use(passport.initialize());
    app.use(passport.session());
    app.set('port', process.env.PORT || 8080);
});

Thank you for your help

感谢您的帮助

采纳答案by Thomas

Make sure to configure your $http request to use credentials. From the XHR documentation:

确保将您的 $http 请求配置为使用凭据。从 XHR 文档:

https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS

https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS

The most interesting capability exposed by both XMLHttpRequest and Access Control is the ability to make "credentialed" requests that are cognizant of HTTP Cookies and HTTP Authentication information. By default, in cross-site XMLHttpRequest invocations, browsers will not send credentials. A specific flag has to be set on the XMLHttpRequest object when it is invoked.

XMLHttpRequest 和访问控制公开的最有趣的功能是能够发出识别 HTTP Cookie 和 HTTP 身份验证信息的“凭据”请求。默认情况下,在跨站点 XMLHttpRequest 调用中,浏览器不会发送凭据。调用 XMLHttpRequest 对象时,必须在其上设置特定标志。

You can use the options object to set the use of credentials, see

您可以使用选项对象来设置凭据的使用,请参阅

http://docs.angularjs.org/api/ng.$http

http://docs.angularjs.org/api/ng.$http

Example:

例子:

$http({withCredentials: true, ...}).get(...)

回答by Fred Mériot

I solved the problem by setting {withCredential : true}in the angular $httprequest and by setting :

我通过设置{withCredential : true}角度$http请求和设置解决了这个问题:

res.header("Access-Control-Allow-Credentials", true);

in my express server configuration. By doing this, my cookie appears well in my browser cookies list.

在我的快速服务器配置中。通过这样做,我的 cookie 会很好地出现在我的浏览器 cookie 列表中。

回答by josh3736

How are you checking for the existence of the cookie?

你如何检查cookie的存在?

$httpis just a wrapper around the browser's XHR, just like jQuery's $.ajaxand friends. That means your browser will handle the cookies normally.

$http只是浏览器 XHR 的包装器,就像 jQuery$.ajax和朋友一样。这意味着您的浏览器将正常处理 cookie。

My guess is that the cookie isbeing set, but you're trying to read it through document.cookie. HttpOnlyprevents script from having access to the cookie. This is a good thing.

我的猜测是,该cookie被设定的,但你想通过读它document.cookieHttpOnly阻止脚本访问 cookie。 这是一件好事。

HttpOnlyhelps mitigate against XSS attacks. It makes it impossible for malicious script to steal a user's session token (and thus their login). Do not turn off HttpOnly.

HttpOnly有助于缓解 XSS 攻击。这使得恶意脚本不可能窃取用户的会话令牌(以及他们的登录信息)。 不要关闭HttpOnly

You should not need the cookie anyway. Since $httpis just a wrapper around XHR, the browser will automatically send the cookie the next time you make a request. You can verify this by watching the requests in the Developer Tools' Network panel.

无论如何,您不应该需要cookie。由于$http它只是 XHR 的包装器,浏览器将在您下次发出请求时自动发送 cookie。您可以通过查看 Developer Tools 的 Network 面板中的请求来验证这一点。

回答by Vatsal Shah

Below solution worked for me

以下解决方案对我有用

In Angular, I have used following code snippet using withCredentials: truefor my request.

Angular 中,我使用了以下代码片段 withCredentials: true用于我的请求。

this._http.post(this._apiUrl + 'api/' + url, data, { withCredentials: true })
            .subscribe(data => { resolve(data) }, error => { this.showServerError(error)})

In Node, before I got the solution, I was just initializing CORSusing

在 Node 中,在我得到解决方案之前,我只是使用初始化CORS

app.use(cors());

But, now I have implemented the following code snippet

但是,现在我已经实现了以下代码片段

app.use(cors({origin: [
   "http://localhost:5000"
 ], credentials: true}))

Where http://localhost:5000is my Angular application endpoint. You can set this URL dynamically from config or .env file.

其中http://localhost:5000是我的 Angular 应用程序端点。您可以从 config 或 .env 文件动态设置此 URL。

Hope that above solution will work for your problem.

希望上述解决方案可以解决您的问题。

回答by robertklep

You can change it by configuring express.session:

您可以通过配置更改它express.session

app.use(express.session({
  secret : 'this is a secret',
  cookie : {
    httpOnly : false,
    maxAge   : XXX // see text
  }
});

But I don't think Angular cares much about cookies, those are handled by the browser (and I agree with @josh3736 that you should keep httpOnlyto true).

但我不认为角关心太多关于cookies,这些是由浏览器处理(和我一起@ josh3736同意,你应该保持httpOnlytrue)。

It might have something to do with your cookies being (browser-)session cookies. You can try and see if it works better by explicitly setting a maxAgefor the cookie (in milliseconds).

这可能与您的 cookie 是(浏览器-)会话 cookie 有关。您可以通过maxAge为 cookie显式设置 a (以毫秒为单位)来尝试查看它是否效果更好。