实现登录_Flask 实现登录功能

本文介绍了如何使用Flask实现登录功能,包括注册用户、登录验证和登录状态保持。通过Flask-SQLAlchemy操作数据库,利用jwt库生成Token进行鉴权,并提供login_required装饰器用于保护受限制的路由。
摘要由CSDN通过智能技术生成

在大多数人学习 web 开发的路线图中,登录功能往往是我们接触到的第一个功能,本文对 flask 实现登录功能做一个简单的介绍。

需求的分析往往是实现的第一步,在对 flask 的登录功能进行编码 demo 之前,有必要先介绍一下登录模块的功能列表和基本流程。

一个登录功能主要要实现如下几个基本的功能点:

  1. 注册新用户到数据库
  2. 判断一个登录请求是成功还是失败,即登录功能
  3. 登录状态的保持

实现上述功能的基本流程如下:

  • 注册新用户到数据库

fdaa867c92159b939664a2beb0f61042.png
  • 登录功能

62edd608b03111b7f29f366343459353.png
  • 登录状态保持:

58ab0e3bca995aed23db4c65fd24aad5.png

下面给出上述功能的简单的实现。这里需要用到 Flask-SQLAlchemy 模块以访问数据库,有关 Flask-SQLAlchemy 的介绍在这里:

胡文七:Flask SQLAlchemy 链接数据库​zhuanlan.zhihu.com
813c96bc37ef8c562bdf46a13420de7e.png

定义用户对象

我们继承了 SQLAlchemy.Model 类来实现一个 User 类:

代码如下:

from flask_sqlalchemy import SQLAlchemy


db = SQLAlchemy()


class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(24), nullable=False)
    password = db.Column(db.String(24), nullable=False)

    def __init__(self, username, password):
        self.username = username
        self.password = password

注册功能

注册功能和 flask_login 没有关系,只需要将注册表单中的数据提交到数据库即可,代码如下:

@app.route("/register", methods=["POST"])
def register():
    proto = request.get_json()

    # 判断是否已经注册,如果已经注册,则返回已经注册的信息
    if User.query.filter_by(username = proto["username"]).first():
        return jsonify({
            "state": RegisterState.ALREADY.name
        })
    else:
        db.session.add(User(**proto))
        db.session.commit()
        
        return jsonify({
            "state": RegisterState.SUCCESS.name
        })
    
    return jsonify({
        "state": RegisterState.UNKNOWN.name
    })

登录功能

我们采用 Token 的方式来实现登录功能,我们在用户请求数据包中提取 username 和 password,然后在数据库中进行查询,如果查询到了这个用户,那么我们就给前端返回一个 Token,前端会记录这个 Token,当前端需要鉴权的时候,将该 Token 放入到数据请求当中,就可以访问收到保护的内容:

我们使用 jwt 库来实现 token 的编码和解码,代码如下:

def token_encode(**kwargs):
    return jwt.encode(kwargs, secret_key, algorithm='HS256')
    

def decodeAuthToken(token):
    try:
        payload = jwt.decode(token, secret_key, algorithms=['HS256'])
        if payload["username"] == request.get_json()["username"]:
            return DecodeTokenState.SUCCESS
        return DecodeTokenState.InvalidTokenError
    except jwt.ExpiredSignatureError:
        return DecodeTokenState.ExpiredSignature
    except jwt.InvalidTokenError:
        return DecodeTokenState.InvalidTokenError

借鉴 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 实现了前后端分离的登录,真诚的希望可以和你讨论~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值