配置 Axios 和 Flask 以使用 CORS 和 cookie

ste*_*bdh 4 javascript cookies cors flask axios

前端运行于localhost:3000 服务器运行于localhost:9000

我可以在不访问 cookie 的情况下发出 CORS 请求。

示例 Axios 请求

axios.post(SERVER+'/createUser', params)
        .then( resp=>{
            //not important
        });
Run Code Online (Sandbox Code Playgroud)

(工作:能够从其他服务器访问资源)

我无法保存/发送服务器localhost:9000设置的 HttpOnly cookie [会话实现]

预期流程

拨电至 localhost:9000/authenticate

localhost:9000/authenticate 返回带有 HttpOnly cookie 的响应

localhost:9000携带此 cookie 的后续请求

为了尝试使用 axios 访问此 cookie,我添加了axios 文档withCredentials:true 引用的标头。为清楚起见:

let headers = {
    withCredentials:true
}
export function authenticate(creds){
    return dispatch => {
        axios.post(SERVER+'/authenticate', creds, headers)
            .then( resp => {
                //not important
            });
    };
}
Run Code Online (Sandbox Code Playgroud)

之后我收到以下错误:

加载http://localhost:9000/authenticate失败:对预检请求的响应未通过访问控制检查:响应中“Access-Control-Allow-Origin”标头的值不能是通配符“*”当请求的凭据模式为“包含”时。因此,不允许访问Origin ' http://localhost:3000 '。XMLHttpRequest 发起的请求的凭证模式由 withCredentials 属性控制。

为清楚起见,发送第一个 (OPTIONS) 请求,并在“成功”响应后抛出错误。选项请求: 选项请求响应信息

我的服务器使用Flask-Cors库,在阅读了cookie 文档和其他一些链接后,这是为 CORS 设置服务器的方式

... normal app init
app = Flask(__name__, static_url_path='/static')
...
cors = CORS(app, origins=["http://localhost:3000"], headers=['Content-Type'], expose_headers=['Access-Control-Allow-Origin'], supports_credentials=True)
...
@app.route('/authenticate', methods=['POST'])
def authenticate():
    ...
Run Code Online (Sandbox Code Playgroud)

我只将方法设置为 POST,因为 (1) cookie 文档也将其限制为 POST 和 (2) OPTIONS 请求似乎通过(如图像所引用)和 (3) 当我确实包含 OPTIONS 作为可能的方法时路由,当第一个请求被发送时,它进入方法,我不知道返回什么,所以如果有人知道当包含 OPTIONS 方法时什么是正确的响应,请发布。

其他链接

https://github.com/axios/axios/issues/569

当 Postman 没有时,为什么我的 JavaScript 会收到“请求的资源上不存在‘Access-Control-Allow-Origin’标头”错误?

CORS:当凭据标志为真时,不能在 Access-Control-Allow-Origin 中使用通配符

Set-Cookie 标头没有效果

bvd*_*vdb 7

该代码看起来像您定义withCredentials为 HTTP 标头。但这并不是它的工作原理。

withCredentials 实际上是一个启用 http 标头的选项,但它本身并不是一个 http 标头。

尝试创建这样的承诺:

const axiosWithCookies = axios.create({
  withCredentials: true
});
const promise = axiosWithCookies.get(url);
Run Code Online (Sandbox Code Playgroud)

生成的 http 标头实际上如下所示。但是您不必手动添加它。如果您如上所述创建 axios 实例,这将得到处理。

Cookie: JSESSIONID=...
Run Code Online (Sandbox Code Playgroud)