交叉(子)域jQuery.ajax查询烧瓶应用程序接收cookie但无法发送它们

问题描述 投票:0回答:1

我有两个域名:

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.comapi.localhost.com)。它们都具有相同的内容(用户名,访问令牌和oauth_state [在GitHub OAuth期间需要])并指示身份验证成功。

我不明白的是:

  1. 为什么我会得到两个cookie,特别是为什么来自ajax: https://api.localhost.com/v1/login的会话cookie存储在localhost.com而不是api.localhost.com
  2. Github OAuth正在工作,这意味着redirect: https://api.localhost.com/callback会收到https://api.localhost.com/v1/login设置的会话cookie,并且可以使用数据(oauth_state)。然而,随后的ajax: https://api.localhost.com/v1/Username不会发送会话cookie。为什么?

我希望我已经包含了所有必要的内容。这是一个非常令人费解的问题,现有的SO问题都没有帮助我超越这一点。任何帮助或指针都非常感谢。

ajax session cookies flask cors
1个回答
0
投票

(2)我使用$.getJSON错了。它很简单,很疼。

作为per the documentation

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,这是预期的行为。

© www.soinside.com 2019 - 2024. All rights reserved.