iT邦幫忙

2023 iThome 鐵人賽

DAY 11
0

前言

在昨天教導大家如何建立database至於接下來終於來到重頭戲,我將帶大家使用flask login來實現登入功能。

介紹

Flask-Login 是 Flask 應用程式中常用的用戶身份驗證和管理套件。它提供了方便的方法來處理用戶登入、登出、保護路由、管理用戶會話等功能。以下是使用 Flask-Login 實現用戶登入的基本步驟:

  1. 安裝 Flask-Login:
    開啟終端機,執行以下指令進行安裝:

    pip install Flask-Login
    
  2. 初始化 Flask-Login:
    在你的 Flask 應用程式中,導入 flask_login 模組並初始化 LoginManager 物件,例如:

    from flask import Flask
    from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user
    
    
    app = Flask(__name__)
    login_manager = LoginManager()
    login_manager.init_app(app)
    
  3. 定義用戶模型(User Model):
    User 類別繼承自 UserMixin,UserMixin 提供了一些用於處理用戶登入功能的方法和屬性。在這個例子中,User 類別不需要任何額外的內容,所以只有 pass。

    @login_manager.user_loader 裝飾器
    該裝飾器用於註冊用戶加載函式(user_loader),用於從用戶識別符(user_id)加載用戶。在這個例子中,user_loader 函式從資料庫中查詢用戶的密碼,並創建一個 User 物件,將用戶識別符設定為 user_id,最後返回該用戶。

    @login_manager.request_loader 裝飾器
    該裝飾器用於註冊請求加載函式(request_loader),用於從請求中加載用戶。在這個例子中,request_loader 函式從請求表單(request.form)中獲取用戶識別符(user_id),然後從資料庫中查詢用戶的密碼。如果密碼匹配,則創建一個 User 物件,將用戶識別符設定為 user_id,最後返回該用戶。如果密碼不匹配,則返回 None。

    class User(UserMixin):
     pass
    
     @login_manager.user_loader
     def user_loader(user_id):
    
         db = get_db()
         password = db.execute(
             'SELECT password FROM members WHERE account = ?', (user_id, )
         ).fetchall()
    
         if not password:
             return
    
         user = User()
         user.id = user_id
         return user
    
     @login_manager.request_loader
     def request_loader(request):
    
         user_id = request.form.get('ID')
    
         db = get_db()
         password = db.execute(
             'SELECT password FROM members WHERE account = ?', (user_id, )
         ).fetchall()
    
         if not password:
             return
    
         user = User()
         user.id = user_id
    
         # DO NOT ever store passwords in plaintext and always compare password
         # hashes using constant-time comparison!
    
         return user if (request.form['password'] == password[0][0]) else None
    
  4. 設定用戶登入視圖:
    實現用戶登入的視圖(endpoint),接受用戶提供的登入資訊,並進行驗證。驗證成功後,可以使用 login_user() 函式將用戶登入。例如:

    from flask import request, redirect
    from flask_login import login_user
    
    @app.route('/login', methods=['POST'])
    def login():
        # 從 POST 請求中獲取用戶名稱和密碼
        username = request.form['username']
        password = request.form['password']
    
        # 進行用戶驗證,驗證成功時登入用戶
        if verify_user(username, password):
            user = User(username)  # 創建 User 物件,根據自己的需求進行實現
            login_user(user)  # 登入用戶
            return redirect('/dashboard')
        else:
            return 'Invalid username or password'
    
  5. 設定登出視圖:
    實現用戶登出的視圖(endpoint),使用 logout_user() 函式將用戶登出。例如:

    from flask_login import logout_user
    
    @app.route('/logout')
    def logout():
        logout_user()  # 登出用戶
        return redirect('/login')
    
  6. 保護路由:
    設定需要用戶驗證的路由,只允許登入的用戶訪問。你可以使用 @login_required 裝飾器來標記需要保護的路由。
    例如:

    from flask_login import login_required
    
    @app.route('/dashboard')
    @login_required  # 需要用戶登入才能訪問
    def dashboard():
        return 'Welcome to the dashboard'
    

總結

今天簡單的介紹,讓讀者了解 Flask-Login 功能。至於更詳細的串接將在明天介紹給大家。


上一篇
[Day-10] flask登入功能(2) 串接SQLite
下一篇
[Day-12] Flask登入功能(4)-登入範例
系列文
Flask30天教學-從入門到入土30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
rockywang
iT邦新手 5 級 ‧ 2024-02-06 15:35:04

請問已經有寫 login 來取得使用者的資料了
@app.route('/login', methods=['POST'])

那麼,request_loader 與 user_loader 的用意是什麼? 何時會觸發?

@login_manager.user_loader@login_manager.request_loader 是 Flask-Login 庫中的裝飾器,用於在 Flask 應用程序中處理用戶身份驗證。這兩個裝飾器的用途略有不同:

  1. @login_manager.user_loader 裝飾器:

    • 這個裝飾器用於定義一個回調函數,該函數接受用戶ID作為參數。
    • 當 Flask-Login 需要加載一個用戶的信息時,它會調用這個函數。
    • 這個函數通常從數據庫中檢索用戶,並根據用戶ID返回對應的用戶對象。
    • 這是用於處理用戶會話和記住用戶狀態(例如,通過cookies)的基本機制。
    @login_manager.user_loader
    def load_user(user_id):
        return User.query.get(user_id)
    
  2. @login_manager.request_loader 裝飾器:

    • 這個裝飾器用於定義一個回調函數,該函數接受一個 Flask 請求對象作為參數。
    • 它允許開發者根據請求本身(如標頭或數據)來加載和認證用戶。
    • 這對於API或非瀏覽器客戶端非常有用,例如在使用令牌或API密鑰進行認證時。
    • 這個裝飾器提供了比 user_loader 更高的靈活性,因為它可以訪問整個請求對象。
    @login_manager.request_loader
    def load_user_from_request(request):
        # 可以從請求中提取API密鑰或令牌,並返回相應的用戶對象
        api_key = request.headers.get('Authorization')
        if api_key:
            return User.query.filter_by(api_key=api_key).first()
        return None
    

總而言之就是要取得id當parameter而已

我要留言

立即登入留言