[英]Angularjs $http does not seem to understand “Set-Cookie” in the response
I have a nodejs express REST api with Passport module for authentication. 我有一个nodejs用Passport模块表示REST api进行身份验证。 A login method (GET) returns a cookie in the header. 登录方法(GET)在标头中返回一个cookie。 When I call it from Chrome it works fine, my cookie is set in my browser. 当我从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? 也许HttpOnly可能是这个问题的根源? 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 谢谢您的帮助
Make sure to configure your $http request to use credentials. 确保配置$ http请求以使用凭据。 From the XHR documentation: 从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. XMLHttpRequest和Access Control公开的最有趣的功能是能够发出认证HTTP Cookie和HTTP身份验证信息的“凭证”请求。 By default, in cross-site XMLHttpRequest invocations, browsers will not send credentials. 默认情况下,在跨站点XMLHttpRequest调用中,浏览器不会发送凭据。 A specific flag has to be set on the XMLHttpRequest object when it is invoked. 调用XMLHttpRequest对象时,必须在其上设置特定标志。
You can use the options object to set the use of credentials, see 您可以使用options对象设置凭据的使用,请参阅
http://docs.angularjs.org/api/ng.$http http://docs.angularjs.org/api/ng.$http
Example: 例:
$http({withCredentials: true, ...}).get(...)
How are you checking for the existence of the cookie? 你是如何检查cookie的存在的?
$http
is just a wrapper around the browser's XHR, just like jQuery's $.ajax
and friends. $http
只是浏览器XHR的包装器,就像jQuery的$.ajax
和朋友一样。 That means your browser will handle the cookies normally. 这意味着您的浏览器将正常处理cookie。
My guess is that the cookie is being set, but you're trying to read it through document.cookie
. 我的猜测是,该cookie 被设置,但是你想通过读它document.cookie
。 HttpOnly
prevents script from having access to the cookie. HttpOnly
可以防止脚本访问cookie。 This is a good thing. 这是一件好事。
HttpOnly
helps mitigate against XSS attacks. HttpOnly
有助于缓解XSS攻击。 It makes it impossible for malicious script to steal a user's session token (and thus their login). 它使恶意脚本无法窃取用户的会话令牌(以及他们的登录)。 Do not turn off HttpOnly
. 不要关闭HttpOnly
。
You should not need the cookie anyway. 无论如何你不应该需要cookie。 Since $http
is just a wrapper around XHR, the browser will automatically send the cookie the next time you make a request. 由于$http
只是XHR的包装,因此浏览器会在您下次发出请求时自动发送cookie。 You can verify this by watching the requests in the Developer Tools' Network panel. 您可以通过在开发人员工具的“网络”面板中查看请求来验证这一点。
I solved the problem by setting {withCredential : true}
in the angular $http
request and by setting : 我通过在角度$http
请求中设置{withCredential : true}
并设置以下内容来解决问题:
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列表中。
Below solution worked for me 以下解决方案适合我
In Angular , I have used following code snippet using withCredentials: true
for my request. 在Angular中 ,我使用withCredentials: true
使用以下代码片段withCredentials: true
对于我的请求,为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 CORS using 在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:5000 is my Angular application endpoint. http:// localhost:5000是我的Angular应用程序端点。 You can set this URL dynamically from config or .env file. 您可以从config或.env文件动态设置此URL。
Hope that above solution will work for your problem. 希望以上解决方案能够解决您的问题。
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 httpOnly
to true
). 但是我认为Angular不太关心cookie,这些是由浏览器处理的(我同意@josh3736你应该保持httpOnly
为true
)。
It might have something to do with your cookies being (browser-)session cookies. 它可能与您的cookie(浏览器)会话cookie有关。 You can try and see if it works better by explicitly setting a maxAge
for the cookie (in milliseconds). 您可以通过显式设置cookie的maxAge
(以毫秒为单位)来尝试查看它是否更好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.