{"id":23094,"library":"flask-security","title":"Flask-Security","description":"Flask-Security is a library that adds common security features to Flask applications, including authentication, role management, password hashing, email confirmation, and session management. Current version is 5.8.0, requiring Python >=3.10. Released under pallets-eco as the successor to Flask-Security-Too.","status":"active","version":"5.8.0","language":"python","source_language":"en","source_url":"https://github.com/pallets-eco/flask-security","tags":["flask","security","authentication","roles","pallets-eco"],"install":[{"cmd":"pip install flask-security","lang":"bash","label":"Install latest"}],"dependencies":[],"imports":[{"note":"Old class name was FlaskSecurity, now it's Security.","wrong":"from flask_security import FlaskSecurity","symbol":"Security","correct":"from flask_security import Security"},{"note":"","wrong":null,"symbol":"SQLAlchemyUserDatastore","correct":"from flask_security import SQLAlchemyUserDatastore"},{"note":"","wrong":null,"symbol":"UserMixin","correct":"from flask_security import UserMixin"},{"note":"","wrong":null,"symbol":"RoleMixin","correct":"from flask_security import RoleMixin"},{"note":"login_required is exported at package level, direct import is preferred.","wrong":"from flask_security.decorators import login_required","symbol":"login_required","correct":"from flask_security import login_required"}],"quickstart":{"code":"from flask import Flask\nfrom flask_sqlalchemy import SQLAlchemy\nfrom flask_security import Security, SQLAlchemyUserDatastore, UserMixin, RoleMixin, login_required\n\napp = Flask(__name__)\napp.config['SECRET_KEY'] = 'super-secret'\napp.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'\napp.config['SECURITY_PASSWORD_SALT'] = 'salty-salt'\n\ndb = SQLAlchemy(app)\n\nclass Role(db.Model, RoleMixin):\n    id = db.Column(db.Integer, primary_key=True)\n    name = db.Column(db.String(80), unique=True)\n    description = db.Column(db.String(255))\n\nclass User(db.Model, UserMixin):\n    id = db.Column(db.Integer, primary_key=True)\n    email = db.Column(db.String(255), unique=True)\n    password = db.Column(db.String(255))\n    active = db.Column(db.Boolean())\n    confirmed_at = db.Column(db.DateTime())\n    roles = db.relationship('Role', secondary='roles_users', backref=db.backref('users', lazy='dynamic'))\n\nclass RolesUsers(db.Model):\n    id = db.Column(db.Integer, primary_key=True)\n    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))\n    role_id = db.Column(db.Integer, db.ForeignKey('role.id'))\n\nuser_datastore = SQLAlchemyUserDatastore(db, User, Role)\nsecurity = Security(app, user_datastore)\n\n@app.route('/')\n@login_required\ndef home():\n    return 'Hello, user!'\n\nwith app.app_context():\n    db.create_all()\n    if not User.query.filter_by(email='test@example.com').first():\n        user_datastore.create_user(email='test@example.com', password='password')\n        db.session.commit()\n\nif __name__ == '__main__':\n    app.run()","lang":"python","description":"Minimal Flask-Security app with SQLAlchemy user store, showing setup of User/Role models, Security init, and a protected route."},"warnings":[{"fix":"Update imports: 'from flask_security import Security' instead of 'from flask_security_too import FlaskSecurity'.","message":"Flask-Security-Too has been merged into Flask-Security 5.x. The import paths changed: use 'flask_security' (not 'flask_security_too'). The class name for Security init changed from 'FlaskSecurity' to 'Security'.","severity":"breaking","affected_versions":"<5.0 vs >=5.0"},{"fix":"Use 'from flask_security import login_required'.","message":"The 'login_required' decorator from 'flask_security.decorators' is deprecated; import from 'flask_security' directly.","severity":"deprecated","affected_versions":">=5.0"},{"fix":"Set 'SECURITY_REGISTERABLE = True' and configure 'SECURITY_LOGIN_USER_TEMPLATE' etc.","message":"When using custom forms, you must register custom templates in 'SECURITY_REGISTERABLE' and related config options, else forms may not render correctly.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-01T00:00:00.000Z","next_check":"2026-07-30T00:00:00.000Z","problems":[{"fix":"Change import to 'from flask_security import Security'.","cause":"Flask-Security 5.x renamed the class from FlaskSecurity to Security.","error":"ImportError: cannot import name 'FlaskSecurity' from 'flask_security'"},{"fix":"Ensure the secondary table for roles (e.g., 'roles_users') is defined as a SQLAlchemy model with proper foreign keys.","cause":"Missing backref or roles_users table not defined correctly.","error":"TypeError: 'NoneType' object is not subscriptable when accessing user.roles"},{"fix":"Make sure Flask-Login is installed and 'flask_security' is initialized after the app config is set.","cause":"Flask-Security's login_required decorator expects the current_user proxy to be available (via Flask-Login).","error":"AttributeError: 'NoneType' object has no attribute 'get' when using login_required"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}