我有一个前端vue网站,托管在谷歌的firebase上,网址为(https://front-end.web.com),而我的flask后端托管在heroku上,带有url(https://back-end.heroku.com)。这使得我的会话无法在请求中持续存在,我试图通过在后端实现CORS来解决这个问题,但由于某种原因,它不起作用,下面是我的代码片段,以显示我的实现
config_class.py
class ConfigClass():
CORS_ALLOW_HEADERS = ['Content-Type']
CORS_ORIGINS = ['https://front-end.web.com']
SECRET_KEY = os.environ.get("APP_SECRET_KEY")
SESSION_TYPE = 'redis'
_init.py
from flask import Flask, session
from flask_session import Session
from flask_cors import CORS
from root_folder.config import ConfigClass
db = SQLAlchemy()
migrate = Migrate()
ma = Marshmallow()
sess = Session()
def create_app(ConfigClass):
# initiate the flask app and assign the configurations #
app = Flask(__name__)
app.config.from_object(config_options[config_class])
sess.init_app(app)
from root_folder.clients import clients_app
# register all the blueprints in this application
app.register_blueprint(clients_app)
CORS(app, supports_credentials=True)
# return the app object to be executed
return app
应用程序
from root_folder import create_app
app = create_app()
Procfile:
web: gunicorn -w 1 app:app
axios前端请求
let formData = new FormData();
formData.append("email", email);
formData.append("password", password);
axios.post(
backendUrl+'create_client_account',
formData,
{
withCredentials: true,
headers:{
"Content-Type": "multipart/form-data"
}
}
);
创建客户端路由(我已经将这个代码块剥离到最低限度,以使其易于理解(:
from flask import session
# route for creating account credentials
@bp_auth_clients_app.route("/create_client", methods=["POST"])
def create_client():
username = request.form.get("username").lower()
email = request.form.get("email").lower()
# create account code goes here #
auth_authentication = True
session["auth_authentication"] = auth_authentication
req_feedback = {
"status": True,
"message": "Account was successfully created",
"data": feedback_data
}
return jsonify(req_feedback), 200
成功创建帐户后,我无法在后续请求中访问会话值,返回None。
为了在我的本地服务器上重现问题,我通过域"访问前端;localhost:8080",而我通过";127.0.0.1:8000"。如果我将前端域更改为"0";127.0.0.1:8080";,我通常没有任何问题。
请提供建议。
由于Ahmad的建议,我能够使用前端和后端的自定义域解决问题,如下所示:
frontend.herokuapp.com -> customDomain.com
backend.herokuapp.com -> api.customDOmain.com
最后,我在会话配置中添加了以下行:
SESSION_COOKIE_DOMAIN = ".customDomain.com"
一切都很好。
会话使用cookie:在创建会话时,服务器将在设置的cookie头中发送cookie值。由于跨来源问题,它对您不起作用。
当您使用127.0.0.1
时,它对您来说很好,因为127.0.0.1:8080
和127.0.0.1:8000
是同源的,所以浏览器接受set-cookie
标头并设置cookie没有问题。
cookie会在每个请求的标头中发送,您的服务器会根据cookie值(cookie值称为session_id(从Redis
加载会话
插入方式=>通常情况下,在请求生命周期结束时,您的会话会被序列化并插入Redis中,cookie哈希作为Key。
如果你想继续使用会话和cookie,你需要为你的部署找到另一个解决方案,以便你的后端和前端拥有相同的主机名。
如果你做不到,我建议你读一下JWT(Json网络代币(。
编辑 您可以在响应正文中发送会话id,并将其保存在本地存储中。
然后您需要配置:frontend将会话id值设置为编码的Authorization
标头base64。Backendbase64解码请求中的Authorization
头值,并在Redis中检查会话,如果存在,则加载它。
编辑
如何使用apache在同一主机名上部署后端/前端:使用apache,您需要创建两个虚拟主机,一个用于后端,另一个用于在不同端口上侦听前端,然后如果路径以/api/
为前缀,则将web服务器部署配置为使用后端VH,并将前端虚拟主机用于其他任何事情。这样,你对你的api的任何请求,你的后端都会处理它,否则它将为你的前端应用程序服务。这只是一种方法,还有很多其他方法检查这个问题。