【问题标题】:flask sessions not persistent between requests from cross domains跨域请求之间的烧瓶会话不持久
【发布时间】:2022-01-07 22:07:14
【问题描述】:

我有一个前端 vue 站点托管在 google 的 firebase 上,网址为 (https://front-end.web.com),而我的烧瓶后端托管在 heroku 上,网址为 (https://back-end.heroku.com)。这使我的会话不会在请求之间持续存在,我尝试通过在后端实现 CORS 来解决此问题,但由于某种原因它不起作用,下面是我的代码的 sn-ps 以显示我的实现

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'

_初始化.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

app.py

from root_folder import create_app

app = create_app()

过程文件:

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

账号创建成功后,后续请求无法访问session值,返回None。

为了在本地服务器上重现问题,我通过域 "localhost:8080" 访问前端,同时通过 "127.0.0.1:8000" 访问烧瓶服务器。如果我把前端域改成“127.0.0.1:8080”,一般是没有问题的。

请给点建议。

【问题讨论】:

    标签: flask session axios cross-domain


    【解决方案1】:

    会话使用 cookie: 在创建会话时,服务器将在 set-cookie 标头中发送 cookie 值。由于跨源问题,它对您不起作用。

    当您使用127.0.0.1 时,它对您很有效,因为127.0.0.1:8080127.0.0.1:8000 是同一个来源,所以浏览器接受set-cookie 标头并设置cookie 没问题。

    Cookie 在每个请求的标头中发送,您的服务器通过 cookie 值(cookie 值称为 session_id)从 Redis 加载会话。
    如何插入 => 通常,您的会话会在请求生命周期结束时以 cookie 哈希作为 Key 序列化并插入 Redis。

    如果您想继续使用会话和 cookie,您需要为您的部署找到另一个解决方案,以使您的后端和前端具有相同的主机名。

    如果您不能这样做,我建议您阅读 JWT (Json-Web-Tokens)。

    编辑 您可以在响应正文中发送会话 ID 并将其保存在本地存储中。

    然后你需要配置: frontendAuthorization 标头base64 编码中设置会话ID 值。 后端 base64 解码请求中的Authorization 标头值并检查Redis 中的会话,如果存在则加载它。

    编辑

    如何使用 apache 在同一主机名上部署后端/前端: 使用 apache,您需要创建 2 个虚拟主机,一个用于后端,另一个用于在不同端口上侦听的前端,然后配置您的 Web 服务器部署以使用后端 VH(如果路径以 /api/ 为前缀),并将前端虚拟主机用于其他任何事情. 这样,您对 api 的任何请求,您的后端都会处理它,否则它将为您的前端应用程序提供服务。 这只是一种方法,还有很多其他方法 Check this question.

    【讨论】:

    • 感谢您的反馈。我听取了您的建议,并将我的前端托管在 heroku 上,这样前端和后端就可以在 heroku 上共享同一个域,如下所示:frontend.herokuapp.com;后端.herokuapp.com。但是我的在线会话仍然存在同样的问题
    • backend.herokuapp.com 和 frontend.herokuapp.com 有不同的主机名。 127.0.01 的情况有效,因为主机名相同但端口不同,有关详细信息,请参阅我编辑的答案。
    • @e_green 检查我的评论和编辑的答案。
    • 感谢您的帮助。您的见解有助于我使用自定义域解决问题。
    【解决方案2】:

    感谢 Ahmad 的建议,我能够使用自定义域为我的前端和后端解决问题,如下所示:

    frontend.herokuapp.com -> customDomain.com
    backend.herokuapp.com -> api.customDOmain.com 
    

    最后我将下面的行添加到我的会话配置中:

    SESSION_COOKIE_DOMAIN = ".customDomain.com"
    

    一切都很好。

    【讨论】:

      猜你喜欢
      • 2013-09-13
      • 2011-03-01
      • 2019-03-14
      • 2019-07-03
      • 2014-04-01
      • 2017-01-08
      • 1970-01-01
      • 2013-08-22
      相关资源
      最近更新 更多