Flask 和前端的会话持久性问题:成功登录后会话丢失

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

我正在开发一个 Web 应用程序,使用 Flask 作为后端,使用 Angular 作为前端。我的前端在

http://localhost:4200
上运行,我的后端在
http://127.0.0.1:5000
上运行。我已经使用 Flask-Login 实现了一个登录系统,但是我遇到了一个问题,即成功登录后会话不会持续存在。

问题描述: 成功登录后,后端会在浏览器中设置会话cookie。但是,当我尝试访问受保护的路由(例如,

http://127.0.0.1:5000/api/player/info
)时,服务器会响应
{"is_authenticated": false}
,表明会话无法识别。

代码示例:

__init__.py:

import os
from flask import Flask
from flask_cors import CORS
from flask_login import LoginManager
from flask_session import Session

from .database import db, migrate
from .models import Player


# Initialize app for Flask-Login
login_manager = LoginManager()
login_manager.login_view = 'auth.login'


@login_manager.user_loader
def load_user(user_id):
    return Player.query.get(int(user_id))


def create_app():
    app = Flask(__name__)
    env_config = os.getenv("APP_SETTINGS", "config.DevelopmentConfig")
    app.config.from_object(env_config)

    # Initialize app for Flask-Session
    Session(app)

    # Handle CORS (Cross-Origin Resource Sharing)
    CORS(app, supports_credentials=True)

    # Initialize app for SQLAlchemy
    db.init_app(app)

    # Initialize app for Flask-Login
    login_manager.init_app(app)

    # Initialize app for Flask-Migrate
    migrate.init_app(app, db)

    # Register blueprints
    from .blueprints import auth_bp, player_bp
    app.register_blueprint(auth_bp, url_prefix="/api/auth")
    app.register_blueprint(player_bp, url_prefix="/api/player")
  
    return app

Flask登录路线:

@auth_bp.route('/login', methods=['POST'])
def login():
    # ... [authentication logic] ...
    login_user(user, remember=remember)
    return jsonify({"message": "Logged in successfully"}), 200

Flask 获取玩家信息的路由:

@player_bp.route('/info', methods=['GET'])
def get_player_info():
    if current_user.is_authenticated:
        return {"is_authenticated": True, "name": current_user.name}
    return {"is_authenticated": False}

Angular 登录服务:

login(userData: { username: string; password: string; remember: boolean }): Observable<any> {
    const url = `127.0.0.1:5000/api/auth/login`;
    return this.http.post(url, userData, { withCredentials: true });
}

采取的步骤:

  1. 登录函数对用户进行身份验证并调用
    login_user(user, remember=remember)
  2. CORS 配置为
    supports_credentials=True
    来处理跨域请求。
  3. Angular HttpClient 配置为
    { withCredentials: true }
    以确保会话 cookie 与请求一起发送。
  4. 我验证了登录后在浏览器中设置了会话 cookie。
  5. 我检查了后续请求的请求标头,并且会话 cookie 正在发送到服务器。
  6. 我尝试使用 Flask 的默认会话管理和 Flask-Session 与 Redis,但问题仍然存在。
  7. 为了进一步隔离问题,我创建了一个基本的 HTML 和 JavaScript 页面并将其托管在不同的端口上,类似于我的 Angular 设置。这个最小的设置旨在与 Flask 后端交互。尽管简化了前端环境,我还是遇到了相同的会话持久性问题:登录后建立的会话似乎无法被后续请求识别,这表明该问题可能不是 Angular 特定的,而是可能与会话管理或跨会话处理有关。跨不同端口的原始请求。

预期行为: 成功登录后,我预计后续对

http://127.0.0.1:5000/api/player/info
的 GET 请求将产生如下 JSON 响应:

{
  "is_authenticated": true,
  "name": "foo"
}

这表明会话正确持续,并且服务器正在确认用户的身份验证状态,同时提供关联的用户信息。

我将不胜感激任何解决此问题的见解或建议。谢谢!

python authentication flask session-state flask-login
1个回答
0
投票

对于那些面临同样问题的人,我通过以下方式解决了这个问题:

  1. 将以下内容添加到我的 __init__.py 中:
 app.config.update(SESSION_COOKIE_SAMESITE="None", SESSION_COOKIE_SECURE=True)
  1. 确保我的 javascript 请求包含:
credentials: 'include' 

更多信息在这里:Flask 会话不保留数据

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