浏览器不存储 cookie

Browser doesn't store cookies

我正在从 Laravel 应用程序 (http://backend.local) 向 Vue SPA (http://frontend.local:8080) 发送 Cookie:

Laravel 侧(虚拟路由)

//api routes
Route::post('login', function () {
    setcookie("name", 'value', time()+3600, "/", ".local");
    return response('ok');
});

Vue 端

axios.post('//backend.local/api/login')
    .then(response => {
        console.log(response)
    }).catch(error => {
})

回复Headers:

HTTP/1.1 200 OK
Date: Mon, 21 May 2018 09:42:35 GMT
Server: Apache
Set-Cookie: name=value; expires=Mon, 21-May-2018 10:42:36 GMT; Max-Age=3600; path=/; domain=.local
Cache-Control: no-cache, private
Access-Control-Allow-Origin: http://frontend.local:8080
Vary: Origin
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
Content-Length: 2
Keep-Alive: timeout=10, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

但是浏览器存储中没有Cookies(开发者控制台中的应用程序选项卡)。 怎么了?


更新:我认为问题是 http://frontend.local:8080 中有端口号。我可以从 url 中删除端口号吗?

由于这是一个 CORS 调用,您需要将 setCredentials 设置为 true。这是标准行为:默认情况下标准 CORS 请求不发送或设置任何 cookie。

withCredentials 属性 将在请求中包含来自其他域的任何 cookie,并设置来自其他域的任何 cookie。

因此您的 Vue.js 代码将是:

axios.defaults.withCredentials = true
axios({
    method: 'POST',
    url: '//backend.local/api/login',

    // THIS IS IMPORTANT
    withCredentials: true
})
.then(response => {
    console.log(response)
}).catch(error => {})

[编辑]:在 HTML Rocks 阅读更多关于 CORS 的信息。

如果没有帮助,请告诉我。

原答案

浏览器将自动拒绝任何不包含两个部分的域。所以使用 .local 根本不被认为是一个域。你至少需要两个级别。考虑下面我为演示相同内容而创建的烧瓶应用程序

from flask import Flask, request, make_response

app = Flask(__name__)

@app.route("/")
def index():
    resp = make_response()

    resp.set_cookie('value1', ".frontend.local", domain=".frontend.local")
    resp.set_cookie('value2', "frontend.local", domain="frontend.local")
    resp.set_cookie('value3', ".local", domain=".local")
    return resp

app.run(debug=True)

现在通过 curl 进行测试

$ curl -v frontend.local:5000
* Rebuilt URL to: frontend.local:5000/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to frontend.local (127.0.0.1) port 5000 (#0)
> GET / HTTP/1.1
> Host: frontend.local:5000
> User-Agent: curl/7.54.0
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Content-Type: text/html; charset=utf-8
< Set-Cookie: value1=.frontend.local; Domain=.frontend.local; Path=/
< Set-Cookie: value2=frontend.local; Domain=frontend.local; Path=/
< Set-Cookie: value3=.local; Domain=.local; Path=/
< Content-Length: 0
< Server: Werkzeug/0.14.1 Python/3.6.5
< Date: Tue, 29 May 2018 12:58:20 GMT
<
* Closing connection 0

当您在浏览器中导航时,您可以看到带 Domain=.local 的 cookie 被丢弃,但其余 2 保留

稍后您可以看到两个cookie都已发送到同一页面的重新加载

更新 1:2018 年 5 月 30 日

由于您使用的是 2 个不同的域,因此您应该使用 frontend.local.combackend.local.com,并且应该将 cookie 与域一起返回为 .local.com,以便 backendfrontend 作为 local.com 的子域。然后 frontend.local.com 通过域共享获取 backend.local.com 设置的 cookie,因为 cookie 域设置为 .local.com