Flask-Admin with Flask Security登录到admin后端

时间:2018-03-19 22:29:47

标签: flask flask-admin flask-security

我更新了我的用户模型:

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    first_name = db.Column(db.String(255))
    last_name = db.Column(db.String(255))
    email = db.Column(db.String(255), unique=True)
    password = db.Column(db.String(255))
    active = db.Column(db.Boolean())
    confirmation = db.Column(db.Boolean)
    email_confirmation_sent_on = db.Column(db.DateTime, nullable=True)
    confirmed_at = db.Column(db.DateTime, nullable=True)
    registered_on = db.Column(db.DateTime, nullable=True)
    last_login_at = db.Column(db.DateTime, nullable=True)
    current_login_at = db.Column(db.DateTime, nullable=True)
    last_login_ip = db.Column(db.String)
    current_login_ip = db.Column(db.String)
    login_count = db.Column(db.Integer)
    roles = db.relationship('Role', secondary=roles_users,
                            backref=db.backref('users', lazy='dynamic'))

要:

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    first_name = db.Column(db.String(255))
    last_name = db.Column(db.String(255))
    email = db.Column(db.String(255), unique=True)
    _password = db.Column(db.String(255))
    active = db.Column(db.Boolean())
    confirmation = db.Column(db.Boolean)
    email_confirmation_sent_on = db.Column(db.DateTime, nullable=True)
    confirmed_at = db.Column(db.DateTime, nullable=True)
    registered_on = db.Column(db.DateTime, nullable=True)
    last_login_at = db.Column(db.DateTime, nullable=True)
    current_login_at = db.Column(db.DateTime, nullable=True)
    last_login_ip = db.Column(db.String)
    current_login_ip = db.Column(db.String)
    login_count = db.Column(db.Integer)
    roles = db.relationship('Role', secondary=roles_users,
                            backref=db.backref('users', lazy='dynamic'))


    @hybrid_property
    def password(self):
        return self._password

    @password.setter
    def set_password(self, plaintext):
        self._password = hash_password(plaintext)

所以,我可以从User模型中散列密码。但是,现在我无法登录到用户后端。我认为这是因为它无法识别用户内置表单中的_password?有没有办法可以利用@password.setter装饰器并仍然使用Flask-security?

1 个答案:

答案 0 :(得分:0)

我对Flask-Security并不是很熟悉,所以这是一个猜测:

Flask-Security可能正在使用您的密码属性,但您自己的密码哈希和Flask-Security可能会相互干扰。

您可以通过重新定义set_password来简单地设置明文来测试:

@password.setter
def set_password(self, plaintext):
    self._password = plaintext

如果这样可以解决您的登录问题,您可以通过创建第二个属性/装饰器(两者都在._password上运行)和指向flask-admin来获得您想要的烧瓶管理和烧瓶安全性。问题在于,您需要确保密码哈希算法匹配(因此您可能希望在两个位置重复使用Flask-Security)。这可能如下所示:

# models.py
class User(db.Model, UserMixin):
    ...
    _password = db.Column(db.String(255))
    ...

    @hybrid_property
    def password(self):
        return self._password

    @password.setter
    def set_password(self, hashed):
        self._password = hashed

    @hybrid_property
    def override_password(self):
        return self._password

    @override_password.setter
    def override_password(self, plaintext):
        self._password = hash_password(plaintext)

# admin.py
class UserView(MyModelView):
    form_columns = ('email', 'override_password', ...)

也可以通过自定义/配置Flask-Security或处理登录流和密码哈希的底层包来获得您想要的内容。