Flask-Login 讓實現登入功能變簡單

weixin_34378969發表於2018-12-21

Web 的登入管理是一個比較複雜的過程,之前寫過一篇基於 Rest API的登入實現(在這裡),最近看到一篇思誠之道寫基於 Flask-Login 的實現方法,不由讚歎,示例和講述寫得太棒了,基本是一看就懂,寫作方法值得自己好好學習。本文是本人在學習這篇部落格時的筆記。

Flask-Login 幫我們做了哪些事?

  • Flask-Login 通過 user session,提供登入的常見任務,比如登入 (logging in)、登出 (logging out) 和當前使用者 (current user)
  • login_user() 函式:實現使用者的登入,一般在登入的檢視函式中呼叫
  • logout_user() 函式:實現登出功能
  • current_user 屬性:獲取當前使用者
  • 對於使用者來說,如果需要頁面是授權使用者才可見,在相應檢視函式前加上 @login_required 裝飾器進行宣告即可,@login_required 裝飾器對於未登入使用者訪問,預設處理是重定向到 LoginManager.login_view 所指定的檢視

如何使用 Flask-Login ?

1. 定義 User

登入基於使用者,需要定義 User 類,Flask-Login 規定 User 類必須實現三個屬性和一個方法:

  • is_authenticated 屬性
  • is_active 屬性
  • is_anonymous 屬性
  • get_id() 方法

最簡單的方法是從 UserMixin 類繼承,該類提供了預設的實現。

# models.py

from flask_login import UserMixin

class User(UserMixin):
    pass

users = [
    {'id':'Tom', 'username': 'Tom', 'password': '111111'},
    {'id':'Michael', 'username': 'Michael', 'password': '123456'}
]

def query_user(user_id):
    for user in users:
        if user_id == user['id']:
            return user

為了簡單和便於理解,使用者名稱和密碼直接寫在程式碼中。

2. 應用程式的配置

建立 LoginManager 例項,然後與 app 繫結。

from flask_login import LoginManager

login_manager = LoginManager()
login_manager.login_view = 'login'
login_manager.login_message_category = 'info'
login_manager.login_message = 'Access denied.'
login_manager.init_app(app)

3. user_loader 回撥函式

user session 記錄的是使用者 ID (user_id),回撥函式的作用就是通過 user_id 返回對應的 User 物件。user_loader 回撥函式在 user_id 非法的時候不應該丟擲異常,而要返回 None。沒有這個回撥函式的話,Flask-Login 將無法工作

@login_manager.user_loader
def load_user(user_id):
    if query_user(user_id) is not None:
        curr_user = User()
        curr_user.id = user_id

        return curr_user

4. 登入功能實現

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        user_id = request.form.get('userid')
        user = query_user(user_id)
        if user is not None and request.form['password'] == user['password']:

            curr_user = User()
            curr_user.id = user_id

            # 通過Flask-Login的login_user方法登入使用者
            login_user(curr_user)

            return redirect(url_for('index'))

        flash('Wrong username or password!')

    # GET 請求
    return render_template('login.html')

關鍵就是 login_user(curr_user) 這句程式碼,之前要構建 User 物件,並指定 id。

5. 登出功能實現

@app.route('/logout')
@login_required
def logout():
    logout_user()
    return 'Logged out successfully!'

原始碼

本文原始碼連線

參考

相關文章