Flask 常用封装,用户登录,验证码,用户信息获取,上传文件

 utils工具封装        # utils文件夹下创建封装py文件

MD5加密封装 

import hashlib


def md5_jm(password):
    md5 = hashlib.md5()
    md5.update(password.encode())
    return md5.hexdigest()

 token封装

import jwt
from flask import current_app


def generate_token(payload):
    key = current_app.config.get('SECRET_KEY')
    token = jwt.encode(payload=payload, key=key, algorithm='HS256')
    return token

redis封装 

import redis
from flask import current_app


class RedisTool:
    rds = None

    def __init__(self, app=None):
        if app:
            self.init_app(app)

    def init_app(self, app):
        redis_url = app.config.get('REDIS_URL')
        self.rds = redis.Redis.from_url(redis_url)


redis_tool = RedisTool()

 容联云封装

import json

from flask import current_app
from ronglian_sms_sdk import SmsSDK


class SmsTool():
    sdk = None

    def __init__(self):
        # 构造函数作用,就是在类实例化的时候自动调用该方法
        # 获取容联云平台的相关参数
        accId = current_app.config.get('ACC_ID')
        accToken = current_app.config.get('ACC_TOKEN')
        appId = current_app.config.get('APP_ID')

        self.sdk = SmsSDK(accId, accToken, appId)

    def send_message(self, mobile, code):
        tid = current_app.config.get('TID')
        sms_time = current_app.config.get('SMS_TIME')
        rs = self.sdk.sendMessage(tid, mobile, (code, sms_time))
        rs_data = json.loads(rs)
        if rs_data['statusCode'] == '000000' or rs_data['statusCode'] == '112310':
            return True
        else:
            return False

 用户蓝图导包

import os
import random
import time
from datetime import datetime

import jwt
from flask import Blueprint, jsonify, current_app, g, request
from flask_restful import Api, Resource, reqparse

from models.models import UserModel, db
from utils.RedisTool import RedisTool
from utils.jwt_token import generate_token
from utils.sms_code import SmsTool

强制登录 功能装饰器

# 强制登录
def login(func):  # 接收一个函数func作为参数 返回一个函数wrapper
    def wrapper(*args, **kwargs):
        req = reqparse.RequestParser()
        req.add_argument('token', location='headers')
        arg = req.parse_args()
        # 判断token是否已经被禁用
        rds = RedisTool().rds
        is_exists = rds.exists('token_%s' % args['token'])  # exists判断键是否存在
        if is_exists:  # redis中有这个token 代表此token已禁用
            return jsonify({
                'code': 403, 'msg': '用户未登录'
            })

        key = current_app.config.get('SECRET_KEY')
        try:
            payload = jwt.decode(arg['token'], key, algorithms='HS256')
        except:
            return jsonify({
                'code': 403,
                'msg': '用户未登录'
            })
        g.user_id = payload['user_id']  # g对象生成全局变量
        return func(*args, **kwargs)  # 内部函数 返回参数func

    return wrapper

 发送验证码

# 发送验证码
class SmsCodeView(Resource):
    def get(self, mobile):
        code = str(random.randint(100000, 999999))
        # 调用封装的方法
        rs = SmsTool().send_message(mobile, code)
        # 调用封装的方法
        rds = RedisTool().rds
        rds.set('sms_%s' % mobile, code)
        rds.close()
        if rs:
            return jsonify({
                'code': 200,
                'msg': '发送成功'
            })
        else:
            return jsonify({
                'code': 400,
                'msg': '发送失败'
            })

 登录注册,退出登录

# 登录注册及退出登录
class LoginView(Resource):
    def post(self):
        # 接收参数
        req = reqparse.RequestParser()
        req.add_argument('mobile')
        req.add_argument('code')
        args = req.parse_args()
        # 校验参数
        rds = RedisTool().rds
        code = rds.get('sms_%s' % args['mobile'])
        if not code:
            return jsonify({
                'code': 400,
                'msg': '验证码已过期'
            })
        if args['code'] != code.decode():
            return jsonify({
                'code': 400,
                'msg': '验证码错误'
            })
        user_info = UserModel.query.filter(UserModel.mobile == args['mobile']).first()
        if not user_info:
            username = '游客' + args['mobile'][-4:]
            u = UserModel(username=username, mobile=args['mobile'])
            db.session.add(u)
            db.session.commit()
        user_info = UserModel.query.filter(UserModel.mobile == args['mobile']).first()
        payload = {
            'user_id': user_info.uid,
            'username': user_info.username,
            'mobile': user_info.mobile,
            # 'exp': int(time.time()) + 5
        }
        token = generate_token(payload)
        return jsonify({
            'code': 200, 'msg': '登录成功',
            'data': {
                'token': token
            }
        })

    @login
    def delete(self):
        # 获取token
        req = reqparse.RequestParser()
        req.add_argument('token', location='headers')
        args = req.parse_args()
        token = args['token']
        # 退出登录时创建一个token到redis数据库
        # 在强制登录装饰器判断 redis中是否有这个键 如果有 则禁用
        rds = RedisTool().rds
        rds.set('token_%s' % token, '1', ex=7200)
        rds.close()
        return jsonify({
            'code': 200, 'msg': '退出登录成功'
        })

 用户信息获取,修改

# 用户信息
class UserInfoView(Resource):
    # 获取用户信息
    @login
    def get(self):
        user_id = g.user_id  # 通过g对象 多个函数之间可以调用
        user_info = UserModel.query.get(user_id)
        if not user_info:
            return jsonify({
                'code': 403,
                'msg': '用户不存在'
            })
        return jsonify({
            'code': 200,
            'data': {
                'user_id': user_info.uid,
                'username': user_info.username,
                'mobile': user_info.mobile,
                'img': user_info.img,
                'host': 'http://rissceunh.sabkt.gdipper.com/'
            }
        })

    # 修改用户信息
    @login
    def put(self):
        # 1.获取用户id
        user_id = g.user_id
        # 2.接收参数
        req = reqparse.RequestParser()
        req.add_argument('username')
        req.add_argument('img')
        args = req.parse_args()
        # 3.获取对象
        user_info = UserModel.query.get(user_id)
        # 4.接收的参数有值 才进行修改
        if args['username']:
            user_info.username = args['username']
        if args['img']:
            user_info.img = args['img']
        db.session.commit()
        # 5.返回响应
        return jsonify({
            'code': 200, 'msg': '用户信息修改成功'
        })

上传文件

# 上传文件
class UploadView(Resource):
    def post(self):
        img = request.files.get('img')
        if not img:
            return jsonify({
                'code': 400, 'msg': '没有接收到文件'
            })
        filename = datetime.strftime(datetime.now(), '%Y%m%d%H%M%S')
        filename += str(random.randint(100000, 999999))
        filename += '.'
        filename += img.filename.split('.')[-1]
        # img.save('./static/'+filename)
        img.save(os.path.join('static', filename))

        from qiniu import Auth, put_file

        # 需要填写你的 Access Key 和 Secret Key
        access_key = 'v4JRKhMbX_X3n5WNvxCSmWYzqiNs3jzG_KJedmrR'
        secret_key = 'uDv2qMfPCJmJDZ5DgYhx8iGgUPGXm6B3zfzeaD0R'
        # 构建鉴权对象
        q = Auth(access_key, secret_key)
        # 要上传的空间
        bucket_name = 'flask11'
        # 上传后保存的文件名
        key = 'static/' + filename
        # 生成上传 Token,可以指定过期时间等
        token = q.upload_token(bucket_name, key, 3600)
        # 要上传文件的本地路径
        localfile = './static/' + filename
        info = put_file(token, key, localfile)
        print(info)
        if info[0]['key'] == key:
            return jsonify({
                'code': 200, 'msg': '上传成功',
                'data': {
                    'filename': key
                }
            })
        else:
            return jsonify({
                'code': 400, 'msg': '上传失败'
            })

 路由


api.add_resource(SmsCodeView, '/smscode/<mobile>')
api.add_resource(LoginView, '/login')
api.add_resource(UserInfoView, '/info')
api.add_resource(UploadView, '/upload')

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值