You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask 2.3.2集成Flask-Security 3.0.0时before_first_request报错求助

问题:Flask-Security roles_required装饰器触发AttributeError

错误详情

AttributeError: 'Flask' object has no attribute 'before_first_request'. Did you mean: '_got_first_request'?

当前Flask-Login的@login_required装饰器可正常使用,仅在使用Flask-Security的@roles_required时触发该错误。

相关代码文件

run.py

from app import create_app, db
from config import Config
from app.models import User

app = create_app(Config)

if __name__ == '__main__':
    app.run(debug=True)

models.py

import secrets
from datetime import datetime

from flask import current_app, request
from flask_security import UserMixin, RoleMixin
from itsdangerous import URLSafeTimedSerializer

from app import db

# Define association table for many-to-many relationship
roles_users = db.Table('roles_users', db.metadata,
    db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
    db.Column('role_id', db.Integer(), db.ForeignKey('role.id'))
)

class Role(db.Model, RoleMixin):
    id = db.Column(db.Integer(), primary_key=True)
    name = db.Column(db.String(80), unique=True)
    description = db.Column(db.String(255))

class User(UserMixin, db.Model):
    __tablename__ = 'WEB_Users'

    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(120), unique=True, nullable=False)
    first_name = db.Column(db.String(50), nullable=False)
    last_name = db.Column(db.String(50), nullable=False)
    is_active = db.Column(db.Boolean, default=True)
    roles = db.relationship('Role', secondary=roles_users, backref=db.backref('users', lazy='dynamic'))

app/init.py

from flask import Flask, session
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager

# Flask-Login-Manager
login_manager = LoginManager()
login_manager.login_view = 'auth.login'

# Flask-App-Factory
db = SQLAlchemy()
migrate = Migrate()

def create_app(config_class):
    app = Flask(__name__)
    app.config.from_object(config_class)

    # Initialize extensions
    db.init_app(app)
    migrate.init_app(app, db)
    login_manager.init_app(app)
    
    # User loader for Flask-Login
    from app.models import User, Role
    @login_manager.user_loader
    def load_user(user_id):
        return User.query.get(int(user_id))
    
    # Extend session validity
    @app.before_request
    def extend_session():
        session.permanent = True

    # Register blueprints
    from app.auth.routes import auth_bp
    from app.dashboard.routes import dashboard_bp

    app.register_blueprint(auth_bp)
    app.register_blueprint(dashboard_bp)

    # Setup Flask-Security
    from flask_security import Security, SQLAlchemyUserDatastore
    user_datastore = SQLAlchemyUserDatastore(db, User, Role)
    security = Security(app, user_datastore)

    return app

routes.py

from flask import Blueprint, render_template
from flask_login import login_required
from flask_security import current_user, roles_accepted, roles_required

test = Blueprint('test', __name__)

@test.route('/admin')
@login_required
@roles_required('Admin')
def admin():
    print(current_user.roles)
    return "Admin"

解决方案

这个错误的核心原因是Flask 2.3+版本移除了before_first_request方法,而当前使用的Flask-Security版本仍在调用该方法。以下是两种解决途径:

1. 升级Flask-Security到兼容版本

旧版Flask-Security已停止维护,建议切换到官方维护的分支Flask-Security-Too,并确保版本>=5.3.0(该版本已适配Flask 2.3+的变化):

pip install --upgrade flask-security-too

2. 适配应用工厂模式的初始化方式(临时措施)

如果暂时无法升级,可修改app/__init__.py中Flask-Security的初始化代码,改用init_app方法适配应用工厂模式:

# 替换原有的Security初始化代码
from flask_security import Security, SQLAlchemyUserDatastore
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security()  # 先不传入app
security.init_app(app, user_datastore)  # 单独调用init_app

额外注意事项

检查models.py中的关联表外键定义:由于User模型设置了__tablename__ = 'WEB_Users',关联表roles_users中的外键应指向WEB_Users.id而非user.id,否则会导致数据库关联错误,修正如下:

roles_users = db.Table('roles_users', db.metadata,
    db.Column('user_id', db.Integer(), db.ForeignKey('WEB_Users.id')),  # 修正此处
    db.Column('role_id', db.Integer(), db.ForeignKey('role.id'))
)

内容的提问来源于stack exchange,提问作者Shark00n

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 01:12:33