大家好,感谢您的时间和支持!
我目前正在我的身份验证模块中存储会话[“用户名”],然后尝试从后端应用程序(特别是从主端点)从我的项目模块访问它。问题是 session["username"] 从项目模块返回 None,我不知道为什么!!!
我尝试了不同的应用程序配置,ChatGPT 给了我一些建议,甚至创建了一个更简单的项目,其会话功能正常工作,没有问题,我复制了结构,但仍然存在相同的问题。
我做了一些研究,据说前端应用程序不应该成为问题,因为无论前面发生什么(React),后面的会话都应该保持不变。
app.py
from dotenv import load_dotenv
from flask import Flask
from flask_cors import CORS
from flask_session import Session
from models import db
load_dotenv('.env', override=True)
app = Flask(__name__)
app.config['SESSION_TYPE'] = 'filesystem'
app.config['SECRET_KEY'] = 'verysafekey'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
Session(app)
CORS(app, supports_credentials=True, origins=["http://localhost:3000"])
db.init_app(app)
from routes.auth import auth_bp
from routes.project import project_bp
from routes.jira import jira_bp
# Register blueprints
app.register_blueprint(auth_bp)
app.register_blueprint(project_bp)
app.register_blueprint(jira_bp)
if __name__ == '__main__':
with app.app_context():
db.create_all()
app.run(debug=True, port=5000)
模型.py
import os
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
# Initialize SQLAlchemy (deferred app initialization)
db = SQLAlchemy()
# Ensure the user_databases directory exists
if not os.path.exists('user_databases'):
os.makedirs('user_databases')
# User model remains in the main database
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(50), unique=True, nullable=False)
password = db.Column(db.String(100), nullable=False)
# Function to get the SQLAlchemy session for a user's database
def get_user_db_session(username):
user_db_path = f"user_databases/{username}.db"
user_engine = create_engine(f"sqlite:///{user_db_path}")
session_factory = sessionmaker(bind=user_engine)
return scoped_session(session_factory)
def create_user_db(username):
user_db_path = f"user_databases/{username}.db"
if not os.path.exists(user_db_path):
user_engine = create_engine(f"sqlite:///{user_db_path}")
Base.metadata.create_all(user_engine)
# Project and Issue models for the user-specific database
Base = declarative_base()
class Client(Base):
__tablename__ = 'client'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
projects = db.relationship('Project', backref='client', lazy=True)
class Project(Base):
__tablename__ = 'project'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
client_id = db.Column(db.Integer, db.ForeignKey('client.id'), nullable=False)
issues = db.relationship('Issue', backref='project', lazy=True)
class Issue(Base):
__tablename__ = 'issue'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
project_id = db.Column(db.Integer, db.ForeignKey('project.id'), nullable=False)
content = db.Column(db.Text)
auth.py
@auth_bp.route('/login', methods=['POST'])
def login():
data = request.get_json()
username = data.get('username')
password = data.get('password')
session['username'] = username
# Print debug info
print("Session stored username for Login:")
print(session.get("username"))
# Simulate an external API call
url = 'https://urchin-app-veelh.ondigitalocean.app/api/login'
headers = {'Content-Type': 'application/json'}
data = {"username": username, "password": password}
new_response = requests.post(url, json=data, headers=headers)
if new_response.status_code >= 200 and new_response.status_code <= 300:
json_response = new_response.json()
refresh_token = json_response.get('refreshToken')
# Handle user database
user = User.query.filter_by(username=username).first()
if not user:
create_user_db(username)
return jsonify(success=True, user=username, token=refresh_token, message='Username and password match.')
else:
return jsonify(success=False, message='Incorrect username or password. Please try again.')
项目.py
@project_bp.route('/home', methods=['GET'])
def home_internal():
print("Backend /home API reached")
print("Session stored username for Home:")
print(session.get("username"))
username = session.get('username')
if not username:
return jsonify(success=False, message='Username not found in session.')
user_db_session = get_user_db_session(username)
clients = user_db_session.query(Client).all()
projects = user_db_session.query(Project).all()
has_clients = len(clients) > 0
has_projects = len(projects) > 0
return jsonify(success=True, has_clients=has_clients, has_projects=has_projects)
我尝试使用一个更简单的版本,没有前端来完成这个任务,有趣的是,它看起来与我的小项目相似;它仍然为会话中的用户名变量返回 None ;这是使用会话完美运行的虚拟对象。
app.py
from flask import Flask
from flask_session import Session
app = Flask(__name__)
# Configuration for the session
app.config['SECRET_KEY'] = 'supersecretkey'
app.config['SESSION_TYPE'] = 'filesystem'
Session(app)
# Registering blueprints (each blueprint corresponds to a module)
from create_session import create_session_bp
from print_session import print_session_bp
from print_session_again import print_session_again_bp
app.register_blueprint(create_session_bp)
app.register_blueprint(print_session_bp)
app.register_blueprint(print_session_again_bp)
if __name__ == '__main__':
app.run(debug=True)
create_session.py
from flask import Blueprint, session
create_session_bp = Blueprint('create_session_bp', __name__)
@create_session_bp.route('/create_session')
def create_session():
session['username'] = 'test_user'
return "Session variable 'username' set to 'test_user'. <a href='/print_session'>Go to Print Session</a>"
print_session.py
from flask import Blueprint, session
print_session_bp = Blueprint('print_session_bp', __name__)
@print_session_bp.route('/print_session')
def print_session():
username = session.get('username', 'Session variable not set!')
return f"Session variable 'username' is: {username}. <a href='/print_session_again'>Go to Print Session Again</a>"
print_session_again.py
from flask import Blueprint, session
print_session_again_bp = Blueprint('print_session_again_bp', __name__)
@print_session_again_bp.route('/print_session_again')
def print_session_again():
username = session.get('username', 'Session variable not set!')
return f"Session variable 'username' is still: {username}."
我终于明白了!!
我没有包含来自前端的凭据,这最终意味着没有收到会话数据,因此;每次请求后我们都有空值!!
一个小的前后示例:
const response = await fetch('api/here');
const response = await fetch('api/here', {credentials: 'include'});