我收到服务器的回应。响应标题包含有效的Set-Cookie。 Chrome Response / Cookies说我有1个Cookie,好的。但是... cookie没有设置到DevTools / Application / Cookies
/*
My frontend on Vue
I renamed 127.0.0.1 to www.example.com
So running on www.example.com:80 or just www.example.com
*/
let response = await axios({
method: 'post',
url: 'http://127.0.0.1:3000/api/login', // my Node server on 3000 port
data: {
email : login,
password: password,
},
})
/*
My backend part on Node.js+Express
Running on localhost:3000 or 127.0.0.1:3000
CookieParser() is setted
*/
let options = {
maxAge: 345600000,
httpOnly: true,
path: '/',
}
res
.cookie('test', 'test', options)
.cookie('access_token', token, options) //token contains a JWT string
.send('');
/*
Chrome Response Headers
*/
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 0
Content-Type: text/html; charset=utf-8
Date: Sun, 09 Feb 2020 08:52:22 GMT
ETag: W/"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"
Set-Cookie: test=test; Max-Age=345600; Path=/; Expires=Thu, 13 Feb 2020 08:52:22 GMT; HttpOnly
Set-Cookie: access_token=example; Max-Age=345600; Path=/; Expires=Thu, 13 Feb 2020 08:52:22 GMT; HttpOnly
X-Powered-By: Express
/*
Chrome request headers
*/
Accept: application/json, text/plain, '*/*'
Accept-Encoding: gzip, deflate, br
Accept-Language: ru-RU,ru;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 45
Content-Type: application/json;charset=UTF-8
Host: 127.0.0.1:3000
Origin: http://www.example.com
Pragma: no-cache
Referer: http://www.example.com/
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36
此外,我尝试使用Microsoft Edge,但问题并未消失。为什么浏览器考虑到他们了解接收Cookie的原因而无法设置cookie?
答案 0 :(得分:8)
如果您想做一些背景阅读,那么我建议您寻找有关CORS(跨域资源共享)的指南,尤其是使用CORS时如何设置cookie。
使用原始代码,您需要将其更改为将withCredentials
设置为true
:
let response = await axios({
method: 'post',
url: 'http://127.0.0.1:3000/api/login', // my Node server on 3000 port
data: {
email : login,
password: password,
},
withCredentials: true
})
在幕后,这将在withCredentials
上设置XMLHttpRequest
标志:
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials
然后,您会在控制台中收到CORS错误。如果您设法解决这些错误,则应该可以使其正常工作。这些错误将包括...
首先,服务器将需要返回标头Access-Control-Allow-Credentials: true
。这也适用于印前检查OPTIONS请求。
第二,您当前正在使用Access-Control-Allow-Origin: *
,但是使用凭据的请求不允许这样做。必须为Access-Control-Allow-Origin: http://www.example.com
。对于飞行前也是如此。
那时候,应该在大多数浏览器中设置cookie(稍后会详细介绍浏览器)。
要将Cookie添加到后续请求中,您还需要在这些请求上设置withCredentials: true
。上面概述的其他标头更改也需要应用。 Cookie不会包括在预检请求中,而只会包含在主请求中。
在浏览器的开发人员工具中查看Cookie并非一帆风顺。通常,这些工具仅显示与当前页面具有相同来源的cookie,但不包括通过CORS请求设置的cookie。要查看这些cookie,您需要打开另一个浏览器标签,并将URL设置为与CORS请求具有相同来源的开头。不过请注意,您需要选择一个不会设置Cookie本身的URL,否则并不能真正证明任何事情。
检查设置了哪些Cookie的另一种方法是发送另一个请求(使用withCredentials
),然后查看发送了哪些Cookie。
然后,我们遇到了特定于浏览器的问题...
在Safari中,很难通过CORS设置cookie。如果Safari是您的目标浏览器,那么我建议对此做一些进一步的研究。
其次,Chrome 80将大大更改有关CORS Cookie的规则。参见:
https://www.chromium.org/updates/same-site
使用较旧版本的Chrome,您已经在控制台中看到有关此问题的警告。简而言之,将需要在https
上投放CORS Cookie,并设置伪指令Secure
和SameSite=None
。
更新:
自编写此答案以来,我为常见的CORS问题创建了FAQ。可以在https://cors-errors.info/faq#cdc8上找到解释Cookie的部分。
答案 1 :(得分:1)
如果您使用Axios或Fetch-默认情况下,它们不发送cookie。
如果您去检查一下dav工具-(应用程序选项卡-> Cookies),您应该会看到它们。
这不是Chrome问题,而是您尝试将其发送回去的方式,在提取过程中,您需要将credentials: 'include',
添加到选项对象中,而在axios中是{withCredentials: true}
答案 2 :(得分:0)
如果您使用 express,可能会使用 express-session 作为您的会话 cookie。
来自官方文档:https://www.npmjs.com/package/express-session
如果您使用 cross-site origin and https
安全连接:
session: {
cookie: {
maxAge: 1000*60*60*1,
httpOnly: true, //set false if you want to change the cookie using JavaScipt
secure: true,
sameSite: 'none'
}
}
并且不要忘记设置:
app.set('trust proxy', 1)
使用 express js
否则在 localhost
中你可以使用
session: {
cookie: {
maxAge: 1000*60*60*1,
httpOnly: true, //set false if you want to change the cookie using JavaScipt
secure: false,
sameSite: 'lax'
}
}