iT邦幫忙

2021 iThome 鐵人賽

DAY 23
0

上一篇講完了可以在客戶端及伺服端雙向通訊的 WebSocket ,這篇要講的是有關登入系統的 Flask-Login。

Flask-Login 使用

開始使用前當然要先安裝對吧,這邊開一個新的專案,還是使用 pip 來安裝。

$ pipenv install flask-login

等它跑完就安裝好了。接著來看一下架構吧(其實也沒啥架構啦)。

ithome_login
├── app.py
├── config.py  # 依舊還是放有關設定檔的東西
├── db.py  # 雖然它看起來很像資料庫,等一下你就知道完全不是這麼一回事了
├── Pipfile  # 這個跟下面那個舊不用我說了吧
└── Pipfile.lock

先來看一下長得很像資料庫的東西。

db.py

# 下面這坨是我懶得弄資料庫,所以假裝他是資料庫裡記錄資料就好
class Database:
	# users 是類似資料庫裡的紀錄
    users = {
        "0": {
            "email": "test01@gmail.com",
            "password": "123"
        },
        "1": {
            "email": "test02@gmail.com",
            "password": "456"
        }
    }

    user_profile = {
        "0": {
            "username": "test01"
        },
        "1": {
            "username": "test02"
        }
    }

    # 從資料庫裡抓取這個使用者
	@classmethod
    def get_data(self, email):
        for index, data in self.users.items():
            if email in data['email']:
                return {"id": index, **self.users[index]}
        return None

    # 從資料庫裡抓取這個使用者
	@classmethod
    def get(self, user_id):
        return self.user_profile[user_id]

然後來看一下 app.py

from flask import Flask, redirect, request, url_for
# 加上下面這行
from flask_login import LoginManager, UserMixin, login_user, logout_user, current_user, login_required

import config
from db import Database


app = Flask(__name__)
app.config.from_object(config.DevelopmentConfig)

# 初始化 LoginManager
login_manager = LoginManager(app)
# 如果跳到需要先登入才能看的頁面,會自動轉到叫做 login 的 function(也可以自己改)。
login_manager.login_view = "login"


# 繼承 UserMixin 類,可以不設定,可做為 ORM(物件關聯對映) 的東西(我真的不知道怎麼說)
class User(UserMixin):
    pass


# 提供使用者詳細資料,必須設定,current_user 會用到
@login_manager.user_loader
def load_user(user_id):
    user_data = Database.get(user_id)
    if user_data is None:
        return None
    user = User()
    user.username = user_data['username']
    return user


# 登入頁面
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return '''
     <form action='login' method='POST'>
     <input type='text' name='email' id='email' placeholder='email'/>
     <input type='password' name='password' id='password' placeholder='password'/>
     <input type='submit' name='submit'/>
     </form>
                  '''
    elif request.method == 'POST':
        email = request.values.get('email', None)
        password = request.values.get('password', None)

        user_data = Database.get_data(email)
        if (user_data is not None) and (password == user_data['password']):
			# 主要登入部分
            user = User()
            user.id = user_data['id']
            login_user(user)
            return redirect(url_for('home'))
        else:
            return "Account or Password are wrong"
    else:
        return 'Error'


#  登入後畫面
@app.route('/home')
@login_required  # 必須登入才能夠看到的畫面就加上這行,沒登入會自動跳轉到 login_view
def home():
    if current_user.is_active:
        return 'Welcome ' + current_user.username + '<br /><a href=' + url_for('logout') + '><button>Logout</button></a>'


# 登出畫面
@app.route('/logout')
def logout():
    logout_user()
    return 'Logged out'


if __name__ == "__main__":
    app.run()

是不是還不太懂在幹嘛,其實大概只有 5 個東西要注意。

  1. login_user: 在 Session 中紀錄登入的使用者。

  2. logout_user: 在 Session 中刪除紀錄的使用者。

  3. user_loader: 去資料庫抓使用者詳細資料。

  4. current_user: 使用 login_user 紀錄的使用者資料透過 user_loader 抓取使用者詳細資料。

  5. class User(UserMixin): 有關使用者實體的資料(我真的不太會解釋啦)。

大概就這樣,接著直接啟動 Flask 然後用瀏覽器看一下效果吧。

首先是登入畫面

然後是登入後的畫面

最後是登出畫面

那麼就大概這樣,Flask-Login 簡單來說是個很方便的插件,剛開始看起來可能會覺得有點複雜,不過多嘗試幾次就可以懂了(話說上面的那 5 個東西我也是看了像是天書一樣的源碼加上各種 try-error 才好不容易稍微理解,加上我那漸漸不行的中文能力,所以解釋起來可能不是很精確)。

大家掰~掰~


上一篇
Day 22 Flask-SocketIO
下一篇
Day 24 Flask-Mail
系列文
月光下的Flask之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言