我有两个域名:
https://localhost.com # SPA served via Nginx
https://api.localhost.com # Flask API proxied by nginx (uwsgi_pass)
并通过127.0.0.1 localhost.com api.localhost.com
将这两个文件添加到我的主机文件中。
我通过GitHub的oauth服务添加了服务器端oauth2,我可以进行身份验证(我收到一个访问令牌,可以查询GitHub API)。这就是“流程”:
user calls: https://localhost.com
ajax: https://api.localhost.com/v1/login # gets the app's Github OAuth url
# sets a session cookie for
# localhost.com
user calls: https://github.com/... # gets redirected to log in ect.
redirect: https://api.localhost.com/callback
# github redirects to the callback
# can access some session cookie
# (I assume) from localhost.com
redirect: https://localhost.com # now has two session cookies:
# localhost.com
# api.localhost.com
ajax: https://api.localhost.com/v1/username
# this is where it breaks
我为CORS
设置了服务器端api.localhost.com
头文件(来自nginx.conf的代码段)
add_header 'Access-Control-Allow-Origin' "https://localhost.com";
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type, *';
和查询中的withCredentials
参数:
$.getJSON("https://api.localhost.com/v1/login",
{
xhrFields: { withCredentials: true },
},
(response) => {
this.login_url = response;
});
$.getJSON("https://api.localhost.com/v1/username",
{
xhrFields: { withCredentials: true },
},
(response) => {
console.log(response)
this.username = response;
});
第一个跨域ajax: https://api.localhost.com/v1/login
工作并设置一个cookie,所以我认为它配置正确。 (我可能错了。)但是,第二个ajax: https://api.localhost.com/v1/username
似乎没有发送会话cookie,因为我在烧瓶中留下了一个空的会话:
from flask import session
# [ ... ]
def username_get():
return str(list(session.keys())) # returns "[]"
我可以手动解密两个会话cookie(localhost.com
和api.localhost.com
)。它们都具有相同的内容(用户名,访问令牌和oauth_state [在GitHub OAuth期间需要])并指示身份验证成功。
我不明白的是:
ajax: https://api.localhost.com/v1/login
的会话cookie存储在localhost.com
而不是api.localhost.com
?redirect: https://api.localhost.com/callback
会收到https://api.localhost.com/v1/login
设置的会话cookie,并且可以使用数据(oauth_state)。然而,随后的ajax: https://api.localhost.com/v1/Username
不会发送会话cookie。为什么?我希望我已经包含了所有必要的内容。这是一个非常令人费解的问题,现有的SO问题都没有帮助我超越这一点。任何帮助或指针都非常感谢。
(2)我使用$.getJSON
错了。它很简单,很疼。
jQuery.getJSON( url [, data ] [, success ] )
和数据将作为查询参数附加到URL。从而用。替换呼叫
$.ajax({
dataType: "json",
url: "https://api.localhost.com/v1/username",
xhrFields: { withCredentials: true },
success: (response) =>
{
this.username = response;
}
});
(不使用速记)设置适当的xhrField
,现在正确发送cookie。
(1)可能是由缓存或一些临时文件引起的。我关闭了整个服务器,清除了所有临时文件,并使用我的浏览器(Chrome)执行了相同操作。重新启动后,我只获得api.localhost.com
的单个会话cookie,这是预期的行为。