Реализация Flask-Login с несколькими классами пользователей

Я пишу приложение, которое имеет несколько классов, которые функционируют как пользователи (например, школьная учетная запись и учетная запись персонала). Я пытаюсь использовать Flask-Login, чтобы сделать это легко, но я не совсем уверен, как это сделать, чтобы при входе пользователя в систему я мог проверить приложение, принадлежит ли имя пользователя учетной записи школы или учетной записи персонала, а затем войти соответствующим образом. Я знаю, как выяснить, какой тип учетной записи он принадлежит (так как все имена пользователей должны быть unique), но после этого я не уверен, как сказать приложению, что я хочу, чтобы он вошел в систему этого конкретного пользователя. Сейчас у меня только одна универсальная страница входа. Проще ли сделать отдельные страницы входа для учетных записей персонала и школьных учетных записей? Я использую MySQL db через Flask-SQLAlchemy. Любая помощь будет оценена.

4 ответов


вы можете определить каждого пользователя с определенной ролью. Например, пользователь " x "может быть школой, а пользователь" y "может быть "персоналом".

class User(db.Model):

    __tablename__ = 'User'
    id = db.Column(db.Integer,primary_key=True)
    username = db.Column(db.String(80),unique=True)
    pwd_hash = db.Column(db.String(200))
    email = db.Column(db.String(256),unique=True)
    is_active = db.Column(db.Boolean,default=False)
    urole = db.Column(db.String(80))


    def __init__(self,username,pwd_hash,email,is_active,urole):
            self.username = username
            self.pwd_hash = pwd_hash
            self.email = email
            self.is_active = is_active
            self.urole = urole

    def get_id(self):
            return self.id
    def is_active(self):
            return self.is_active
    def activate_user(self):
            self.is_active = True         
    def get_username(self):
            return self.username
    def get_urole(self):
            return self.urole

Flask-login однако еще не имеет концепции ролей пользователей, и я написал свою собственную версию login_required decorator, чтобы переопределить это. Поэтому вы можете использовать что-то вроде:

def login_required(role="ANY"):
    def wrapper(fn):
        @wraps(fn)
        def decorated_view(*args, **kwargs):

            if not current_user.is_authenticated():
               return current_app.login_manager.unauthorized()
            urole = current_app.login_manager.reload_user().get_urole()
            if ( (urole != role) and (role != "ANY")):
                return current_app.login_manager.unauthorized()      
            return fn(*args, **kwargs)
        return decorated_view
    return wrapper

затем вы можете использовать этот декоратор для функции просмотра, такой как:

@app.route('/school/')
@login_required(role="SCHOOL")
def restricted_view_for_school():
    pass

@codegeek я нашел это очень полезным, спасибо. Мне пришлось немного изменить код, чтобы заставить его работать на меня, поэтому я решил бросить его здесь, если он может помочь кому-то еще:

from functools import wraps

login_manager = LoginManager()

...

def login_required(role="ANY"):
    def wrapper(fn):
        @wraps(fn)
        def decorated_view(*args, **kwargs):
            if not current_user.is_authenticated():
              return login_manager.unauthorized()
            if ((current_user.role != role) and (role != "ANY")):
                return login_manager.unauthorized()
            return fn(*args, **kwargs)
        return decorated_view
    return wrapper

Это пример того, что можно сделать. У меня нет опыта использования Flask-SQLAlchemy, но как не должно быть намного больше. В приведенном ниже примере используется SQLAlchemy напрямую.

сначала вы определяете класс, который наследует от Base чтобы он мог быть отображен ORM (декларативный)

class User(Base):

    __tablename__ = 'user_table'
    id = Column(Integer, primary_key=True)
    email = Column(String(45), unique=True)
    name = Column(String(45))
    pwd = Column(String(8))
    user_role = Column(String(15))

    __mapper_args__ = {
        'polymorphic_identity': 'user_table',
        'polymorphic_on': user_role
    }

как только ваш родительский класс класса будет готов, установите другой класс для каждой из ролей, которые вы хотите иметь.

class SchoolAccount(User):
    __tablename__ = 'school_account'
    id = Column(Integer, ForeignKey('user_table.id'), primary_key=True)
    representative_name = Column(String(45))

    __mapper_args__ = {
        'polymorphic_identity': 'school_account'
    } 

Using Flask-Login вы входите в систему пользователь и ограничение доступа на основе ролей.

вот пример системы входа в систему с двумя разными ролями. Это хороший учебник для колбы, колбы-sqlalchemy, колбы-логин: http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-v-user-logins


взгляните на "управление ролями" из Фляга-Безопасность. Его можно легко интегрировать с Flask-Login.