作者:Chancel, 更新:2021 Jan 31, 字数:3944, 已阅:840
开发一个博客程序,对于登录这一块的要求与一般的程序不太一样,一般只有一个用户登录需求
Flask本身提供了非常简洁的登录模块 Flask-Login模块方便我们快速生成登录程序模块
利用这个模块我们可以快速开发一个登录逻辑,再搭配Google Authenticator的二次验证来提高登录安全强度
以下开发环境测试均基于Python3.6.9
首先安装 flask-login 扩展
pip3 install flask-login
然后写一个最简单的Flask应用例子,访问首页返回 hello world
from flask import Flask
app = Flask(__name__)
@app.route('/'):
return 'hello world'
在初始化你的APP时初始化flask-login登录模块,看起来像这样
from flask_login import LoginManager
login_manager = LoginManager()
login_manager.init_app(app)
然后根据flask-login的文档,我们需要设计一个用户类,这个类必须实现以下3种属性1种方法
这几个属性以及方法用于告诉Flask应用当前用户的状态,我们也可以选择直接继承 UserMixin 类,这样我们的类就具备这些属性方法的默认实现了。
class User(UserMixin):
pass
接着声明一个用户加载方法,用于用户登录后访问你的Web应用时告诉Flask应用当前用户是谁
如果返回为空则说明用户不存在或者登录状态无效
@login_manager.user_loader
def load_user(user_id):
# User应为登录用户对象的集合
return User.get(user_id)
添加一个验证用户的蓝图方法
# 用户如果没有登录会被导向这个蓝图进行登录
login_manager.login_view = "manages_blueprint.login"
@manages_blueprint.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
# 请求方法为GET返回登录界面的HTML文档
return render_template('login.html', title='登录')
if request.method == 'POST':
# 请求方法为POST则做登录校验
username = request.json.get('username', None)
password = request.json.get('password', None)
# 判断用户密码是否正确,正确则调用 login_user()方法将用户信息添加到会话中
if username and password:
user = User()
login_user(user, remember=False)
return flask.redirect(next or flask.url_for('index'))
return '认证失败'
上述提到的所有代码整合
from flask_login import LoginManager
from flask import Flask
class User(UserMixin):
pass
app = Flask(__name__)
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = "manages_blueprint.login"
@login_manager.user_loader
def load_user(user_id):
# User应为登录用户对象的集合
return User.get(user_id)
@app.route('/'):
return 'hello world'
@manages_blueprint.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
# 请求方法为GET返回登录界面的HTML文档
return render_template('login.html', title='登录')
if request.method == 'POST':
# 请求方法为POST则做登录校验
username = request.json.get('username', None)
password = request.json.get('password', None)
# 判断用户密码是否正确,正确则调用 login_user()方法将用户信息添加到会话中
if username and password:
user = User()
login_user(user, remember=False)
return flask.redirect(next or flask.url_for('index'))
return '认证失败'
可以看出来Flask的登录设计非常简洁,做博客的登录设计也非常简单
在校验用户信息完成后,只需要调用 login_user方法便可以实现所有登录相关的信息
二步验证,可以参考Google的二步验证说明
借助两步验证,您可以通过密码和手机为帐户提供双重保护 -- By Google
简单讲,就是利用一些特定算法(对称算法)实现服务器与客户端在1分钟内计算出来一个相同的6位数,现在许多的网站都已经支持这种登录绑定类
二步验证可以达到一个非常变态的安全级别,除非别人同时拿到你的密码+你的设备验证码,否则不可能登录你的账户
使用Python来完成一个简单的二步验证只需要引入一个 pyotp 的库即可,一个简单的例子如下
首先安装pyotp
pip3 install pyotp
pyotp的标准实现
import pyotp
SECRET_KEY = pyotp.random_base32()
totp = pyotp.totp.TOTP(SECRET_KEY,interval=60)
print('当前验证码->%s' % totp.now())
qrcode_text = totp.provisioning_uri(name='chancel', issuer_name='Chancel\'s blog')
引入pyotp库之后创建一个KEY,使用这个KEY我们就可以生成一个totp对象
调用这个对象的provisioning_uri我们就可以生成一段二维码的文本,使用任意文本转二维码工具后获得一个二维码
使用Google出品的Google 身份验证器扫描并绑定这个二维码,则可以看到一个动态的6位数,这个动态码将与 totp.now()输出保持一致
totp也支持使用 totp.verify('397231') 这种方法来验证验证码是否正确
使用Flask-login + pyotp我们可以非常简单的实现一个相当安全的登录机制
如果是博客类型的程序,甚至只需要在配置文件中存放一个Secert字符串即可,既安全又方便
唯一美中不足的是,登录时都需要校验一次本地验证码,不过可以适当延长登录有效期来环节这个问题