reactjs - 使用 Flask 遇到 CORS 问题
问题描述
我已经搜索了几个小时试图找到一个体面的解决方案来解决我的问题,但我似乎找不到解决方案。基本上,我使用蓝图将我的 Flask API 分解为两个单独的文件,一个用作主要的 Flask 应用程序,另一个用于处理所有身份验证路由。我遇到了 CORS 问题......在我将它们分开之前,它在flask-cors
库中运行良好。但是,当我使用蓝图将其分解为单独的文件时,它不起作用。我做了很多研究,似乎有几种方法可以做到,但最好的方法似乎是解决服务器端的问题(至少在理论上,因为我还没有找到解决方案)。
应用程序.py
# Third-party libraries
from flask import Flask
from flask_cors import CORS
# Internal imports
from login import login_page
# Flask app setup
app = Flask(__name__)
app.register_blueprint(login_page)
CORS(app)
app.config['CORS_HEADERS'] = 'Content-Type'
if __name__ == "__main__":
app.run(host="localhost", debug=True)
登录.py
# Third-party libraries
from flask import Flask, redirect, request, url_for, Blueprint, render_template, abort
from flask_login import (
LoginManager,
current_user,
login_required,
login_user,
logout_user
)
from oauthlib.oauth2 import WebApplicationClient
import requests
from flask_cors import CORS
login_page = Blueprint('login_page', __name__)
CORS(login_page)
# Login route
@login_page.route('/login', methods=['GET'])
def login():
# Find out what URL to hit for Google login
google_provider_config = get_google_provider_config()
authorization_endpoint = google_provider_config["authorization_endpoint"]
# Use library to construct the request for Google login and provide
# scopes that let you retrieve user's profile from Google
request_uri = client.prepare_request_uri(
authorization_endpoint,
redirect_uri = request.base_url + "/callback",
scope = ["openid", "email", "profile"]
)
return redirect(request_uri)
来自文档: https ://flask-cors.readthedocs.io/en/latest/api.html#using-cors-with-blueprints
这似乎是我正在做的......但它不起作用。
编辑: 反应代码:
authenticate = async () => {
console.log('authenticate called')
const response = await users.get('/login');
}
我添加了一条测试路线,以查看我处理蓝图的方式是否与flask-cors
库不正确,如下所示:
@login_page.route('/test')
def test():
print('test')
return 'test'
果然,我能够在控制台上看到文本打印。所以这让我相信是其他东西阻止我访问谷歌的身份验证服务器。
Flask 应用程序正在运行localhost:5000
,React 应用程序正在运行localhost:3000
。传入redirect
方法 in的字符串login
如下:
然而,这是在使用 React 之前工作的。
Chrome 控制台错误:
从源“http://localhost:3000”访问“...”处的 XMLHttpRequest(从“http://localhost:3000/login”重定向)已被 CORS 策略阻止:否“Access-Control-Allow-” Origin' 标头存在于请求的资源上。
我还在我的 package.json 文件中添加了一个代理,如下所示:
"proxy": "http://localhost:5000"
我从中得到的:https ://blog.miguelgrinberg.com/post/how-to-create-a-react--flask-project/page/3
更新:
我决定采用使用 Nginx 解决这个问题的方法,因为似乎 flask-cors 库不适合这个问题,因为似乎没有解决方案是可能的。
Nginx.conf
user www-data;
worker_processes 1;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 1024;
}
http {
upstream react-client {
server react-client;
}
upstream flask-backend {
server flask-backend;
}
server {
listen 80;
server_name localhost;
location / {
# From docker-compose, react-client port 80 is exposed
proxy_pass http://react-client;
}
# location /login/callback
# location /logout
}
server {
listen 3000;
server_name localhost;
location /login {
proxy_pass http://flask-backend;
}
}
}
码头工人-compose.yml:
version: '3'
services:
reverse-proxy:
image: nginx:1.17.10
container_name: reverse-proxy
depends_on:
- flask-backend
- react-client
volumes:
- ./reverse-proxy/nginx.conf:/etc/nginx/nginx.conf
ports:
- 80:80
react-client:
image: react-client
container_name: react-client
build:
context: ./client
depends_on:
- flask-backend
ports:
- 3000:3000
restart: on-failure
flask-backend:
image: flask-backend
container_name: flask-backend
build:
context: ./api
ports:
- 5000:5000
restart: on-failure
使用 Nginx 配置和 Docker 文件,我可以转到http://localhost:80
将我转发到反应客户端的位置。这一次,我没有收到 CORS 错误,但我确实在我的检查员中收到了这条消息,Failed to load resource: The network connection was lost.
我的理解是这样的:
http://localhost:80
-> http://localhost:3000
,然后当一个按钮被按下时,它会提示新的路由
http://localhost:3000/login
->http://localhost:5000/login
我有两个服务器块,因为 Web 应用程序在端口 3000 上运行,而 Nginx 服务器在端口 80 上运行。
解决方案
而不是CORS(login_page)
尝试CORS(login_page, resources=r'/login')
编辑:解释为什么这可能有效。
您收到的错误表明该/login
路线不允许 CORS。您正在正确地实例化 Flask-CORS,所以我怀疑如果您尝试描绘您希望 CORS 应用于您的特定路线将解决问题。
文档使它看起来CORS(login_page)
应该自动打开到 CORS 的所有路由,但因为这不起作用,尝试上述答案可能会提供更好的结果。