在大多数人学习 web 开发的路线图中,登录功能往往是我们接触到的第一个功能,本文对 flask 实现登录功能做一个简单的介绍。
需求的分析往往是实现的第一步,在对 flask 的登录功能进行编码 demo 之前,有必要先介绍一下登录模块的功能列表和基本流程。
一个登录功能主要要实现如下几个基本的功能点:
- 注册新用户到数据库
- 判断一个登录请求是成功还是失败,即登录功能
- 登录状态的保持
实现上述功能的基本流程如下:
- 注册新用户到数据库
- 登录功能
- 登录状态保持:
下面给出上述功能的简单的实现。这里需要用到 Flask-SQLAlchemy 模块以访问数据库,有关 Flask-SQLAlchemy 的介绍在这里:
胡文七:Flask SQLAlchemy 链接数据库zhuanlan.zhihu.com定义用户对象
我们继承了 SQLAlchemy.Model 类来实现一个 User 类:
代码如下:
from
注册功能
注册功能和 flask_login 没有关系,只需要将注册表单中的数据提交到数据库即可,代码如下:
@app
登录功能
我们采用 Token 的方式来实现登录功能,我们在用户请求数据包中提取 username 和 password,然后在数据库中进行查询,如果查询到了这个用户,那么我们就给前端返回一个 Token,前端会记录这个 Token,当前端需要鉴权的时候,将该 Token 放入到数据请求当中,就可以访问收到保护的内容:
我们使用 jwt 库来实现 token 的编码和解码,代码如下:
def
借鉴 flask-login 模块,我们也实现一个 login_required 装饰器,这样每次需要访问私密内容的时候,我们只需要在路由函数上加入 login_required 装饰就可以了。
def login_required(func):
@wraps(func)
def decorated_view(*args, **kwargs):
proto = request.get_json()
if decodeAuthToken(proto["token"]) == DecodeTokenState.SUCCESS:
return func(*args, **kwargs)
return jsonify({
"STATE": "INVILADE_TOKEN"
})
return decorated_view
登录的路由如下:
@app.route("/login", methods=["POST"])
def login():
proto = request.get_json()
user = User.query.filter_by(username=proto["username"], password=proto["password"]).first()
if user:
token = token_encode(**{"username": user.username})
return jsonify({
"state": LoginState.SUCCESS.name,
"token": token
})
return jsonify({"state": LoginState.FAIL.name})
假如我们需要访问一个用户的 ToDoList,我们就在前面加入装饰器,实例代码如下:
@app.route("/todolist", methods=["POST"])
@login_required
def todolist():
proto = request.get_json()
return "todolist"
(完)
本文对 Flask 实现 Login 功能做了一个简略的说明。欢迎交流和讨论~
彩蛋:在最开始写这篇 blog 的时候,是想采用 flask-login 库来进行说明,但是到在自己进行试验的过程中,发现 flask-login 要和 flask 提供的渲染模板 jinja2 配合使用。这和我准备后续进行学习和讨论的前后端分离(react+flask)的方案不太吻合,因此选择以 Token 的方式来实现一个登录功能。如果有同学基于 flask-login 实现了前后端分离的登录,真诚的希望可以和你讨论~