上一篇讲完了可以在客户端及伺服端双向通讯的 WebSocket ,这篇要讲的是有关登入系统的 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 个东西要注意。
login_user: 在 Session 中纪录登入的使用者。
logout_user: 在 Session 中删除纪录的使用者。
user_loader: 去资料库抓使用者详细资料。
current_user: 使用 login_user 纪录的使用者资料透过 user_loader 抓取使用者详细资料。
class User(UserMixin): 有关使用者实体的资料(我真的不太会解释啦)。
大概就这样,接着直接启动 Flask 然後用浏览器看一下效果吧。
首先是登入画面
然後是登入後的画面
最後是登出画面
那麽就大概这样,Flask-Login 简单来说是个很方便的插件,刚开始看起来可能会觉得有点复杂,不过多尝试几次就可以懂了(话说上面的那 5 个东西我也是看了像是天书一样的源码加上各种 try-error 才好不容易稍微理解,加上我那渐渐不行的中文能力,所以解释起来可能不是很精确)。
大家掰~掰~
>>: Angular 深入浅出三十天:表单与测试 Day23 - Reactive Forms 进阶技巧 - 栏位连动检核逻辑
前面三天已经介绍过在三大主流作业系统上安装 Gradle 的方式,基本上应该已经能够满足 90% 读...
注:发文日和截图的日期不一定是同一天,所以价格计算上和当日不同,是很正常的。 声明:这一系列文章并无...
初学者升级啦 YA!30天了~代表我连续 30 天学习 JS 了!(拍手~) 第一次参加铁人赛,其实...
嗨各位,Tailwind 篇结束了, 不知道会不会有人敲碗更多呢? 还想知道更多的话也没有问题~ ...
今天我们一起来实作用 HTML Template 来显示 To-Do-List 的资料吧! 首先我们...