代码之家  ›  专栏  ›  技术社区  ›  Pablo Fernandez

饼干在哪里吃?

  •  1
  • Pablo Fernandez  · 技术社区  · 5 年前

    我有一个后端和前端在不同的域上运行。后端为前端提供了一个api,我可以同时控制这两个。后端发送一个cookie到前端,我希望前端会在进一步的请求时发送回去。 我不需要javascript来读取cookie,我只希望它从后端获取并发送回后端 是的。

    在这个实验中,后端运行在 http://api.localtest.me:8000 前面是 http://foo.lvh.me:3000 是的。两个主机名都解析为127.0.0.1,因为我目前正在自己的开发计算机上运行它们。

    服务器发送这些cors头:

    Access-Control-Allow-Credentials: true
    Access-Control-Allow-Origin: http://foo.lvh.me:3000
    

    允许客户端与服务器对话并接收cookies。完整的请求和响应如下所示:

    curl.exe -H "Accept: application/json, text/plain, */*" -H "DNT: 1" -H "Origin: http://foo.lvh.me:3000" -H "Referer: http://foo.lvh.me:3000" -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" --verbose http://app.localtest.me:8000/api-v1/current-user/
    
    *   Trying 127.0.0.1...
    * TCP_NODELAY set
    * Connected to app.localtest.me (127.0.0.1) port 8000 (#0)
    > GET /api-v1/current-user/ HTTP/1.1
    > Host: app.localtest.me:8000
    > Accept: application/json, text/plain, */*
    > DNT: 1
    > Origin: http://foo.lvh.me:3000
    > Referer: http://foo.lvh.me:3000
    > User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
    >
    < HTTP/1.1 200 OK
    < Date: Wed, 16 Jan 2019 09:45:37 GMT
    < Server: WSGIServer/0.2 CPython/3.7.1
    < Content-Type: application/json
    < Vary: Accept, Cookie, Origin
    < Allow: GET, HEAD, OPTIONS
    < X-Frame-Options: SAMEORIGIN
    < Content-Length: 2
    < Access-Control-Allow-Credentials: true
    < Access-Control-Allow-Origin: http://foo.lvh.me:3000
    < Set-Cookie:  sessionid=v04omdilmwz13h1vcirdz8r8pd6r5awv; expires=Wed, 30 Jan 2019 09:45:37 GMT; HttpOnly; Max-Age=1209600; Path=/; SameSite=Lax
    <
    {}* Connection #0 to host app.localtest.me left intact
    

    服务器很清楚地发送了 Set-Cookie 是的。现在,当我在chrome中执行完全相同的操作时,请求和响应如下所示:

    enter image description here

    注意缺乏 设置Cookie .那块饼干在哪里吃的?我调试了后端,一步一步地,我看到set cookie头被写入到浏览器的流中。

    前端使用带有凭据的Axios:

    axios.get("http://api.localtest.me:8000/api-v1/current-user/", {withCredentials: true}).then(response => { console.log(response) })
    

    请求,如 response.request 似乎显示 withCredentials 正确设置:

    enter image description here

    我将对Axios的调用替换为:

    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'http://api.localtest.me:8000/api-v1/current-user/', true);
    xhr.withCredentials = true;
    xhr.send(null);
    

    行为完全一样。我改变了 有证件 成为 false 行为也保持不变。这似乎违背了什么 withCredentials is supposed to do (强调我的):

    xmlhttprequest.withcredentials属性是一个布尔值,它 指示跨站点访问控制请求是否应 使用凭据(如cookies)生成 ,授权头或TLS 客户端证书。使用凭据设置对 相同的站点请求。

    在firefox中,情况有点不同。它显示从服务器发送的cookie,但不发送回(在图片中,这不是第一个请求,因此,发送的cookie应该相同):

    enter image description here

    我使用fiddler重新确认了这些是请求和响应中的头:

    enter image description here

    你知道这是怎么回事吗?

    我试着移除 SameSite: lax 从饼干和行为是一样的。

    为了澄清,这些都不是第一个请求,以前的请求应该设置cookie。在这里,您可以看到一个接一个的三个请求:

    enter image description here enter image description here enter image description here

    0 回复  |  直到 5 年前