2013-04-08 31 views
12

我正在編寫一個具有多個用作用戶的類的應用程序(例如,學校帳戶和工作人員帳戶)。我正在嘗試使用Flask-Login來簡化這個過程,但我不太確定如何使它在用戶登錄時可以讓我的應用程序檢查用戶名是否屬於學校帳戶或工作人員帳戶,然後正確登錄。我知道如何確定哪個類型爲它所屬的帳戶(因爲所有用戶名必須是唯一的),但之後我不知道如何告訴應用程序我希望它登錄該特定用戶。現在,我只有一個通用登錄頁面。如果我爲職員帳戶和學校帳戶分別設置登錄頁面,會更容易嗎?我通過Flask-SQLAlchemy使用MySQL數據庫。任何幫助,將不勝感激。使用多個用戶類實現Flask登錄

+0

一種簡化你正在嘗試的方法是使用角色,這樣你就沒有許多不同的類,每個用戶都有自己使用的繼承關係,因爲你使用的是Flask-SQLAlchemy。 – lv10 2013-04-08 14:13:48

+0

問題是我正在使用現有數據庫是分開的,並有單獨的數據 – 2013-05-08 04:01:31

回答

23

您可以定義每個用戶與一個特定的角色。例如,用戶'x'可以是SCHOOL,而用戶'y'可以是'STAFF'。

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 

瓶登錄但是不具有用戶角色的概念還沒有和我寫我自己login_required裝飾的版本重寫。所以,你可能想使用類似:

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 
+0

問題是我有一個現有的數據庫與單獨的SCHOOL和STAFF數據庫中有數據。你認爲這種方式仍然有可能嗎?我可以創建一個不涉及數據庫的通用用戶類,而是包含學校或工作人員帳戶嗎? – 2013-05-07 22:58:09

+0

我不確定我是否非常關注你,但通常情況下,你應該有1個通用的用戶類/模型,通常可以對應1個數據庫表。我強烈建議您使用「角色」的概念,正如我上面所解釋的那樣。它工作得很好。 – codegeek 2013-05-08 14:00:20

+1

這是我採取的方法。非常感謝您提供清晰,有用的答案。 – tmthyjames 2015-09-11 20:05:50

3

這是你可以做的一個例子。我沒有使用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' 
    } 

使用Flask-Login您可以登錄用戶並根據角色限制訪問權限。

這是一個具有兩個不同角色的登錄系統的示例。這是一個很好的教程燒瓶,燒瓶sqlalchemy,燒瓶登錄:http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-v-user-logins

4

@codegeek我發現這是非常有用的,謝謝。我不得不修改代碼一點得到它爲我工作,所以我想我會在這裏掉落的情況下,它可以幫助別人:

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

Flask-Security看看「角色管理」。它可以輕鬆與Flask-Login集成。