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

2020-06-28 16:06:55 浏览数 (1)

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

代码语言:javascript复制
$(venv) pip install passlib # 用于加密密码和验证密码
$(venv) pip install flask-jwt-extended # 用于用户身份验证
用户模型

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

代码语言:javascript复制

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,具体程序如下:

代码语言:javascript复制

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文件中,需要编写的程序如下:

代码语言:javascript复制
from flask_jwt_extended import JWTManager  # 在顶部导入
jwt = JWTManger()  # 与db放在一起
jwt.init_app(app) # 添加到register_plugins函数中
用户注册与登录

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

代码语言:javascript复制

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功能。具体程序如下:

代码语言:javascript复制
from flask import Blueprint
users_bp = Blueprint('users_bp',__name__)
from app.users import routes

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

代码语言:javascript复制
# 这部分程序添加到register_blueprints函数中  
from app.users import users_bp
app.register_blueprint(users_bp,url_prefix='/api/users')
用户身份认证

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

1、创建users数据库

代码语言:javascript复制
$(venv) flask db migrate$(venv) flask db upgrade

2、注册用户

3、登录获取access_token

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

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

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

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

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

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

0 人点赞