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')