专栏首页TalkPythonVue + Flask 实战开发系列(四)

Vue + Flask 实战开发系列(四)

我们上一次实现的接口,任何人都可以请求到数据。这样一来重要的数据,就可以被获取到。为此,我们需要对接口增加一些用户身份认证功能。提高接口数据的安全性。我们需要添加用户身份验证,以确保只有登录的用户可以访问获取数据,所以现在我们将添加用户登录和注册功能。开发功能之前,需要安装该功能需要的包。

$(venv) pip install passlib # 用于加密密码和验证密码
$(venv) pip install flask-jwt-extended # 用于用户身份验证

用户模型

首先,我们需要创建用户模型和模式。在app目录下,添加一个users包。然后在users目录下,新建models.py文件。完成这些后,可以开发我们的用户模型程序了。具体实现程序如下:

from app import db
from passlib.hash import pbkdf2_sha256 as sha256
from marshmallow_sqlalchemy import ModelSchema
from marshmallow import fields

class User(db.Model):
    __tablename__ = 'users'

    id = db.Column(db.Integer,primary_key=True)
    username = db.Column(db.String(120),unique=True,nullable=False)
    password = db.Column(db.String(120),nullable=False)

    def create(self):
        db.session.add(self)
        db.session.commit()
        return self

    @classmethod
    def find_by_username(cls,username):
        return cls.query.filter_by(username=username).first()

    @staticmethod
    def generate_hash(password):
        return sha256.hash(password)

    @staticmethod
    def verify_hash(password,hash):
        return sha256.verify(password,hash)

以上程序我们模型程序,我们定义的用户名和密码两个内容。还增加了按用户名查找用户的方法、生成密码和验证密码的方法。

用户SCHEMA

接下来创建schema.py文件,然后添加用户的schema,具体程序如下:

from marshmallow_sqlalchemy import ModelSchema
from marshmallow import fields
from app.users.models import User
from app import db

class UserSchema(ModelSchema):
    class Meta(ModelSchema.Meta):
        model = User
        sqla_session = db.session

    id = fields.Number(dump_only=True)
    username = fields.String(required=True)

接下来创建routes.py文件,这是我们添加用户登录和注册路由的地方。对于跨应用程序的用户身份验证,我们将使用JWT (JSON Web令牌)身份验证。JWT是一个开放标准,它定义了一种紧凑且自包含的方式,以JSON对象的形式安全地传输信息。JWT是目前世界上流行的一种用户授权方式。在Flask中有一个开源扩展叫做Flask-JWT- extended,它提供了JWT支持和其他有用的方法。我们在开始的已经安装好了这个扩展包。现在直接使用即可。现在我们打开app目录下的__init__.py文件,开始使用JWT的功能。

在__init__.py文件中,需要编写的程序如下:

from flask_jwt_extended import JWTManager  # 在顶部导入
jwt = JWTManger()  # 与db放在一起
jwt.init_app(app) # 添加到register_plugins函数中

用户注册与登录

完成以上程序后,我们就可以编写routes.py的程序了。

from flask import request
from flask_jwt_extended import create_access_token
from app import db
from app.users import users_bp
from app.users.models import User
from app.users.schema import UserSchema
from app.utils.responses import response_with
from app.utils import responses as resp

# 注册
@users_bp.route('/register',methods=['POST'])
def create_user():
    try:
        data = request.get_json()
        data['password'] = User.generate_hash(data['password'])
        user_schema = UserSchema()
        users = user_schema.load(data)
        result = user_schema.dump(users.create())
        return response_with(resp.SUCCESS_201)
    except as Exception as e:
        print(e)
        return response_with(resp.INVALID_INPUT_422)

# 登录
@users_bp.route('/login',methods=['POST'])
def authenticate_user():
    try:
        data = request.get_json()
        current_user = User.find_by_username(data['username'])
        if not current_user:
            return response_with(resp.SERVER_ERROR_404)
        if User.verify_hash(data['password'],current_user.password):
			access_token = create_access_token(identity=data['username'])
            return response_with(resp.SUCCESS_201,value={'message':'Logged in as {}'.format(current_user.username),"access_token":access_token})
        else:
            return response_with(resp.UNAUTHORIZED_401)
    except Exception as e:
        return response_with(resp.INVALID_INPUT_422)

以上程序,就是我们实现的用户注册和登录功能。若想使用这个功能,我们还需要做如下两件事情。第一,编辑users目录下的__init__.py文件,添加Blueprint功能。具体程序如下:

from flask import Blueprint
users_bp = Blueprint('users_bp',__name__)
from app.users import routes

第二,编辑app目录下__init__.py文件,把用户的路由注册到app上。具体程序如下:

# 这部分程序添加到register_blueprints函数中  
from app.users import users_bp
app.register_blueprint(users_bp,url_prefix='/api/users')

用户身份认证

用户身份认证过程中,我们使用flask_jwt_extended扩展包的jwt_required功能,它以装饰器的方式加到需要用户身份认证的接口上。_接下来,我们就来测试验证一下功能。

1、创建users数据库

$(venv) flask db migrate$(venv) flask db upgrade

2、注册用户

3、登录获取access_token

3、为接口增加用户身份认证

这里我们为获取书籍信息接口增加用户身份认证功能。打开books/目录下的routes.py文件增加如下程序:

from flask_jwt_extended import jwt_required  # 在文件顶部导入
@jwt_required  # 用户身份认证装饰器加到下面@books_bp.route('/',methods=['GET']) 

4、访问获取数据信息接口 下图是请求接口,没有做用户授权的情况。

下图是请求接口,增加用户授权的情况。这里使用的Token,就是我们调用登录接口时返回的access_token信息。

如你所见,这就是保护REST接口的方法。在实际应用中,我们还可以使用电子邮件验证和限制用户注册,我们还可以启用基于用户的访问控制,不同类型的用户可以访问特定的api。本次分享内容,全文至此完。

本文分享自微信公众号 - TalkPython(TalkPython),作者:TalkPython

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-06-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 用Python播放和录制声音

    Python语言已经无所不能了,今天就来分享一下,如何使用Python来录制和播放音频文件。

    TalkPython
  • Vue + Flask 实战开发系列(三)

    通过前面两篇文章,我们已经初步实现了一些简单的接口。还有很多需要做的工作,比如项目结构优化,接口请求权限控制等等。接下来,首先来优化一下,我们的项目结构。前面我...

    TalkPython
  • 生成一个指定长度的随机数

    生成随机数在日常工作中的使用率也很高。虽说Python标库自带了生成随机数的功能。但是我想写一个函数,既可以生成数字,又可以生成字符串。而且还可以指定长度,自由...

    TalkPython
  • flask 留言板(flask 39)

    from flask import flash,render_template,redirect,url_for from app import app,db...

    用户5760343
  • 构建 Zookeeper + Dubbo + Spring Boot 的分布式调用项目

    今天给大家介绍一下如何在SpringBoot中搭建Dubbo+Zookeeper来实现不同系统的RPC调用 这里先和大家说一下什么是RPC框架,简单的来说就是远...

    林老师带你学编程
  • HQL语句大全

    Hibernate配备了一种非常强大的查询语言,这种语言看上去很像SQL。但是不要被语法结构 上的相似所迷惑,HQL是非常有意识的被设计为完全面向对象的查询,它...

    shirayner
  • filter和listener的生命周期

    ydymz
  • Spring Cloud Feign 声明式服务调用

    一、Feign是什么?二、Feign的快速搭建三、Feign的几种姿态 参数绑定 继承特性四、其他配置 Ribbon 配置 Hystri...

    cxuan
  • vue系统学习1-内部指令

    v-if: 按需加载dom,可以减轻服务器的压力。 v-show:dom已加载好,调整css dispaly属性,可以使客户端操作更加流畅。

    杨肆月

扫码关注云+社区

领取腾讯云代金券