2013-04-08 16 views
12

Piszę aplikację, która ma wiele klas, które działają jako Użytkownicy (na przykład konto w szkole i konto personelu). Próbuję użyć Flask-Login, aby to ułatwić, ale nie jestem do końca pewien, jak to zrobić, aby po zalogowaniu się mógłbym sprawdzić moją aplikację, czy nazwa użytkownika należy do konta szkolnego, czy nie. lub konto personelu, a następnie zaloguj się prawidłowo. Wiem, jak ustalić, który z nich należy do konta (ponieważ wszystkie nazwy użytkowników muszą być unikatowe), ale po tym czasie nie jestem pewien, w jaki sposób poinformować aplikację, że chcę, aby zalogowała się do tego konkretnego użytkownika. W tej chwili mam tylko jedną uniwersalną stronę logowania. Czy łatwiej jest utworzyć osobne strony logowania dla kont personelu i kont szkolnych? Używam db MySQL przez Flask-SQLAlchemy. Każda pomoc będzie doceniona.Implementacja Flask-Login z wieloma klasami użytkowników

+0

Sposobem upraszczającym to, co próbujesz, jest użycie ról, aby nie mieć wielu różnych klas na użytkownika i używać dziedziczenia, ponieważ używasz Flask-SQLAlchemy. – lv10

+0

Problem polega na tym, że używam istniejących baz danych, które są oddzielne i mają osobne dane. –

Odpowiedz

23

Możesz zdefiniować każdego użytkownika z określoną rolą. Na przykład użytkownik "x" może być SZKOLĄ, a użytkownik "y" może być "PERSONEL".

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 

Kolba Login jednak nie ma pojęcia ról użytkowników i jeszcze napisałem własną wersję login_required dekoratora przesłonić tego. Więc może chcesz używać coś takiego:

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 

Następnie można użyć tej funkcji dekorator na widok jak:

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

Problem polega na tym, że mam istniejącą bazę danych z oddzielną bazą danych SCHOOL i STAFF zawierającą dane. Czy uważasz, że ten sposób będzie nadal możliwy? Czy mogę po prostu utworzyć ogólną klasę użytkownika, która nie odnosi się do bazy danych, ale zamiast tego opakowuje konto szkolne lub konto personelu? –

+0

Nie jestem pewien, czy podążam za tobą, ale zazwyczaj powinieneś mieć 1 ogólną klasę/model użytkownika, który zwykle odpowiada 1 tabeli bazy danych. Zdecydowanie radzę użyć pojęcia "ról", tak jak to wyjaśniono powyżej. Pracuje bardzo dobrze. – codegeek

+1

To jest podejście, które podjąłem.Dziękuję bardzo za jasną, pomocną odpowiedź. – tmthyjames

3

To jest przykład tego, co możesz zrobić. Nie mam doświadczenia w korzystaniu z Flask-SQLAlchemy, ale nie powinno to być coś znacznie odmiennego. Poniższy przykład wykorzystuje bezpośrednio SQLAlchemy.

Najpierw trzeba zdefiniować klasę użytkownika, która dziedziczy Base tak, że może być odwzorowany przez ORM (deklaratywne)

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 
    } 

Gdy klasa klasa dominująca jest gotowy, należy ustawić inną klasę dla każdej z ról, które chcesz mieć.

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' 
    } 

Korzystanie z Flask-Zaloguj się zalogować użytkownika i ograniczyć dostęp w oparciu o role.

Oto przykład systemu logowania z dwiema różnymi rolami. To jest fajny samouczek dla kolby, kolby-sqlalchemy, flask-login: http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-v-user-logins

4

@codegeek Znalazłem to bardzo przydatne, dzięki. Musiałem zmodyfikować kod trochę do dostać pracy dla mnie, więc pomyślałem, że go nie upuścić tutaj w przypadku może pomóc nikomu:

from functools import wraps 

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

spojrzeć na „Zarządzanie rolę” od Flask-Security. Można go łatwo zintegrować z Flask-Login.

Powiązane problemy