Day 23 Flask-Login

上一篇讲完了可以在客户端及伺服端双向通讯的 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": "[email protected]",
            "password": "123"
        },
        "1": {
            "email": "[email protected]",
            "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 才好不容易稍微理解,加上我那渐渐不行的中文能力,所以解释起来可能不是很精确)。

大家掰~掰~


<<:  Rust-30天的心得

>>:  Angular 深入浅出三十天:表单与测试 Day23 - Reactive Forms 进阶技巧 - 栏位连动检核逻辑

第七天:手动安装 Gradle

前面三天已经介绍过在三大主流作业系统上安装 Gradle 的方式,基本上应该已经能够满足 90% 读...

D27-(9/27)-长兴(1717)-化学传产的好公司

注:发文日和截图的日期不一定是同一天,所以价格计算上和当日不同,是很正常的。 声明:这一系列文章并无...

[ Day 30 ] - 初学者升级啦~完赛心得

初学者升级啦 YA!30天了~代表我连续 30 天学习 JS 了!(拍手~) 第一次参加铁人赛,其实...

Day 17:「我们,是好朋友哦~」- Vue 简介

嗨各位,Tailwind 篇结束了, 不知道会不会有人敲碗更多呢? 还想知道更多的话也没有问题~ ...

Day 21- To Do List (8) 利用 HTML Template 呈现资料

今天我们一起来实作用 HTML Template 来显示 To-Do-List 的资料吧! 首先我们...