25

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.

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

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.

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

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

4

5 回答 5

19

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

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

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

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

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

例子:

$http({withCredentials: true, ...}).get(...)
于 2013-10-15T14:55:07.090 回答
5

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

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

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

于 2013-10-16T06:28:40.903 回答
5

您如何检查 cookie 的存在?

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

我的猜测是正在设置 cookie 但您正试图通过document.cookie. HttpOnly阻止脚本访问 cookie。 这是一件好事。

HttpOnly有助于缓解 XSS 攻击。它使恶意脚本无法窃取用户的会话令牌(以及他们的登录名)。 不要关闭HttpOnly

无论如何,你不应该需要 cookie。由于$http只是 XHR 的一个包装器,浏览器会在您下次发出请求时自动发送 cookie。您可以通过查看开发人员工具的网络面板中的请求来验证这一点。

于 2013-10-15T14:46:40.177 回答
2

以下解决方案对我有用

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

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

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

app.use(cors());

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

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

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

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

于 2019-02-06T06:13:24.590 回答
0

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

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

但我认为 Angular 不太关心 cookie,它们是由浏览器处理的(我同意 @josh3736 的观点,你应该坚持下去httpOnlytrue

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

于 2013-10-15T14:46:48.157 回答