Skip to content

Instantly share code, notes, and snippets.

@exhuma
Created February 26, 2016 07:04
Show Gist options
  • Save exhuma/2e915aba6588e352be3b to your computer and use it in GitHub Desktop.
Save exhuma/2e915aba6588e352be3b to your computer and use it in GitHub Desktop.
Flask-Security not working with non-standard id attribute

When using a non-standard id attribute, flask-login does not seem to work. See also pallets-eco/flask-security#472

This gist contains two examples. One is working, the other one isn't. To test, run the app and go to http://localhost:5000

Login: admin@example.com Password: admin

When using working.py, you should see an 'OK' message.

When using broken.py the login will simply not work, and you'll be presented with a new login page.

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.security import Security, SQLAlchemyUserDatastore, \
UserMixin, RoleMixin, login_required
# Create database connection object
db = SQLAlchemy()
# Define models
roles_users = db.Table(
'roles_users',
db.Column('user_id', db.Integer(), db.ForeignKey('user.email')),
db.Column('role_id', db.Integer(), db.ForeignKey('role.name')))
class Role(db.Model, RoleMixin):
name = db.Column(db.String(80), primary_key=True)
description = db.Column(db.String(255))
@property
def id(self):
return self.name
class User(db.Model, UserMixin):
email = db.Column(db.String(255), primary_key=True)
password = db.Column(db.String(255))
active = db.Column(db.Boolean())
confirmed_at = db.Column(db.DateTime())
roles = db.relationship('Role', secondary=roles_users,
backref=db.backref('users', lazy='dynamic'))
@property
def id(self):
return self.email
# Setup Flask-Security
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
# Create app
app = Flask(__name__)
app.config['DEBUG'] = True
app.config['SECRET_KEY'] = 'super-secret'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'
db.init_app(app)
security = Security(app, user_datastore)
# Create a user to test with
@app.before_first_request
def create_user():
db.create_all()
user_datastore.create_user(
email='admin@example.com', password='admin')
db.session.commit()
# Views
@app.route('/')
@login_required
def home():
return 'Hello'
if __name__ == '__main__':
app.run()
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.security import Security, SQLAlchemyUserDatastore, \
UserMixin, RoleMixin, login_required
# Create database connection object
db = SQLAlchemy()
# Define models
roles_users = db.Table(
'roles_users',
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))
description = db.Column(db.String(255))
class User(db.Model, UserMixin):
id = db.Column(db.Integer(), primary_key=True)
email = db.Column(db.String(255), unique=True)
password = db.Column(db.String(255))
active = db.Column(db.Boolean())
confirmed_at = db.Column(db.DateTime())
roles = db.relationship('Role', secondary=roles_users,
backref=db.backref('users', lazy='dynamic'))
# Setup Flask-Security
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
# Create app
app = Flask(__name__)
app.config['DEBUG'] = True
app.config['SECRET_KEY'] = 'super-secret'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'
db.init_app(app)
security = Security(app, user_datastore)
# Create a user to test with
@app.before_first_request
def create_user():
db.create_all()
user_datastore.create_user(
email='admin@example.com', password='admin')
db.session.commit()
# Views
@app.route('/')
@login_required
def home():
return 'Hello'
if __name__ == '__main__':
app.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment