From a003d4c0a0d4fbb1d69a5c1ff6ba3f5a065e3890 Mon Sep 17 00:00:00 2001 From: RainSun Date: Wed, 2 Dec 2020 22:48:54 +0800 Subject: [PATCH] update --- go.sh | 3 + gunicorn.conf.py | 8 + gunicornLi.conf | 13 -- gunicornMe.conf | 13 -- lib/allFunction.py | 329 +++++++-------------------------------- lib/db.py | 93 +---------- lib/login.py | 4 +- lib/pay.py | 105 ------------- lib/signature.py | 37 ----- lib/utils.py | 157 +++++++++++++++++++ qr/qrcode.html | 26 ++-- qrcodeMe.py => qrcode.py | 52 ++----- qrcodeLi.py | 116 -------------- 13 files changed, 252 insertions(+), 704 deletions(-) create mode 100644 go.sh create mode 100644 gunicorn.conf.py delete mode 100644 gunicornLi.conf delete mode 100644 gunicornMe.conf delete mode 100644 lib/pay.py delete mode 100644 lib/signature.py create mode 100644 lib/utils.py rename qrcodeMe.py => qrcode.py (57%) delete mode 100644 qrcodeLi.py diff --git a/go.sh b/go.sh new file mode 100644 index 0000000..b26db36 --- /dev/null +++ b/go.sh @@ -0,0 +1,3 @@ +#!/bin/sh +echo start +gunicorn qrcode:app -c gunicorn.conf.py \ No newline at end of file diff --git a/gunicorn.conf.py b/gunicorn.conf.py new file mode 100644 index 0000000..80f8002 --- /dev/null +++ b/gunicorn.conf.py @@ -0,0 +1,8 @@ +# 并行工作线程数 +workers = 4 +bind = '0.0.0.0:80' +daemon = True +timeout = 120 +accesslog = './logs/acess.log' +errorlog = './logs/error.log' +autostart = True \ No newline at end of file diff --git a/gunicornLi.conf b/gunicornLi.conf deleted file mode 100644 index c32648e..0000000 --- a/gunicornLi.conf +++ /dev/null @@ -1,13 +0,0 @@ -# 并行工作线程数 -workers = 4 -# 监听内网端口5000【按需要更改】 -bind = '127.0.0.1:5001' -# 设置守护进程【关闭连接时,程序仍在运行】 -daemon = True -# 设置超时时间120s,默认为30s。按自己的需求进行设置 -timeout = 120 -# 设置访问日志和错误信息日志路径 -accesslog = './logsLi/acess.log' -errorlog = './logsLi/error.log' -#自动重启 -autostart = True diff --git a/gunicornMe.conf b/gunicornMe.conf deleted file mode 100644 index d335085..0000000 --- a/gunicornMe.conf +++ /dev/null @@ -1,13 +0,0 @@ -# 并行工作线程数 -workers = 4 -# 监听内网端口5000【按需要更改】 -bind = '127.0.0.1:5000' -# 设置守护进程【关闭连接时,程序仍在运行】 -daemon = True -# 设置超时时间120s,默认为30s。按自己的需求进行设置 -timeout = 120 -# 设置访问日志和错误信息日志路径 -accesslog = './logsMe/acess.log' -errorlog = './logsMe/error.log' -#自动重启 -autostart = True diff --git a/lib/allFunction.py b/lib/allFunction.py index e9f23ab..dae9574 100644 --- a/lib/allFunction.py +++ b/lib/allFunction.py @@ -1,303 +1,84 @@ -from db import findUser, findCode, delCode, insertOrderCache, cache2Test, findOrder, insertCode +from db import findUser, delCode, insertCode from login import getOpenid -from pay import checkNotify, createOrderParams +from utils import checkData import re import json -import time import os +# 当前文件地址 +basedir = os.path.abspath(os.path.dirname(__file__)) +# js文件目录地址 +datadir = os.path.join(basedir, '../data') + # 主函数 # 处理登录操作 debug完成 -def manageLogin(request, where): - if checkContent(request.form['code'],request.form['sign']): # 校验 - res = getOpenid(request.form['code'], where) # 获取openid +def manageLogin(request, is_mine): + # 获取openid + res = getOpenid(request.form['code'], is_mine) if res['errcode'] == 200: # 获取成功返回用户信息 - return {'userInfo': findUser(res['errmsg']['openid']), 'openid': res['errmsg']['openid'], 'errcode': 200, 'from': where} + return {'userInfo': findUser(res['errmsg']['openid']), 'openid': res['errmsg']['openid'], 'errcode': 200} else: # 获取失败返回失败信息 - return res - else: - return False # 参数不全或者没通过校验 - -# 用户扫描二维码付款 debug完成 -def findQR(request): - # 这里做不了加密验证,防止攻击 - # 已知ObjectId只包含数字和字母且长度为24位,使用isalnum - codeId = str(request.args.get('id')) - if(len(codeId) == 24): # 长度校验 - if(codeId.isalnum()): # 内容校验 - return findCode(codeId) # 返回code信息 - else: - return False - else: - return False + return res # 小程序刷新用户信息 debug完成 def flash(request): - # 正常的加解密校验 - # 已知openId只包含-、_、数字和字母且长度为28位,使用正则 - if checkContent(request.form['openId'],request.form['sign']): # 校验 + # 已知openId只包含-、_、数字和字母且长度为28位,使用正则 openId = str(request.form['openId']) if(len(openId) == 28): # 长度校验 - pattern = re.compile(r'[^\w-]') - if(pattern.search(openId)): # 内容校验 - return False - else: - return {'userInfo': findUser(openId), 'errcode': 200} # 返回用户信息 + pattern = re.compile(r'[^\w-]') + if(pattern.search(openId)): # 内容校验 + return False + else: + # 返回用户信息 + return {'userInfo': findUser(openId), 'errcode': 200} else: - return False - else: - return False # 参数不全或者没通过校验 + return False # 参数不全或者没通过校验 # 用户删除二维码 debug完成 def delQR(request): - # 正常加解密校验 - # 和findQR一样,校验objectId - if checkContent(request.form['id'],request.form['sign']): # 校验 + # 已知openId只包含-、_、数字和字母且长度为28位,使用正则 codeId = str(request.form['id']) if(len(codeId) == 24): # 长度校验 - if(codeId.isalnum()): # 内容校验 - res = delCode(codeId) # 返回code信息 - if res: - path = '{0}{1}.js'.format('/data/qrcode/data/', codeId) - print(path) - if os.path.exists(path): - os.remove(path) - return res - else: - return res + if(codeId.isalnum()): # 内容校验 + # 返回code信息 + res = delCode(codeId) + if res: + filename = '{0}.js'.format(codeId) + path = os.path.join(datadir, filename) + if os.path.exists(path): + os.remove(path) + return res + else: + return False else: - return False - else: - return False + return False else: - return False - else: - return False + return False # 用户上传二维码 def addQR(request): - # 流程同createOrder一样,但是直接插入到正式表中,然后返回id - dataCache = json.loads(request.form['data']) # josn化,应该能当dist用 - checked = checkData(dataCache) # 校验所有用户上传的内容 - if checked: - res = insertCode(checked) - if res: - res_cache = res - res = json.loads(res) # res是str 转成json - res = res['$oid'] # 取到里边的id - data = findCode(res) # 获取到所有的信息 - try: # 将信息写入文件 - f = open('{0}{1}.js'.format('/data/qrcode/data/', res),'w',encoding="utf-8") - f.write('{0}{1}'.format('var data = ',data)) - f.close() - except IOError: - return False - return {'errcode': 200, 'id': res_cache, 'data':data} - else: - return False - else: - return False - - -# 微信小程序创建订单 debug完成 -def createOrder(request): - # 先就不加MD5校验了 - # 校验所有内容,目前策略:微信支付宝取网址后边的东西校验,qq转义 - # 需要接收的内容 : data : wxcode alcode qqcode username openId node; totalFee - # 判断过程:先看是否为空,不是空进行校验,报错返回False - dataCache = json.loads(request.form['data']) # josn化,应该能当dist用 - checked = checkData(dataCache) # 校验所有用户上传的内容 - if checked: - params = createOrderParams(request.form['totalFee']) # 获取到订单信息 - dataCache = createOrderCache(dataCache, params) # 处理要放进缓存表的数据 - res = insertOrderCache(dataCache) # 放进缓存表 - if res: - return {'params': params, 'errcode': 200} - else: - return False - else: - return False - -# 处理订单异步通知 debug完成 -def manageNotify(request): - check = checkNotify(request.form.to_dict()) # 回调验证 - if check: - res = cache2Test(request.form['out_trade_no'],request.form['payjs_order_id']) # 转移到Test - if res: # 转移成功返回id - return True - else: - return False - else: - return False - -# 小程序查询订单状况 debug完成 -def checkOrder(request): - order_id = findOrder(request.form['out_trade_no']) # 查询到的映射id - if order_id: # 后端还没收到反馈 - order_id = json.loads(order_id)['$oid'] - if order_id: # 查询删除都成功了 - return {'order_id': order_id, 'errcode': 200} - else: - return False - else: - return False - -# 工具函数--------------------------------------------------------------------------------- - -# 在这里进行解密对照 -def checkContent(row,rsa): - # 回头再写,先默认返回true - # 用那个MD5 - # 应该和MD5放在一个文件里 - return True - -# 判断str转换完是否为空 -def isKong(arg): - if arg == 'None' or arg == '' or arg == None: - return True - else: - return False - -# 上传参数校验 -def checkData(data): - hrefCount = 0 - usernameCount = 0 - openIdCount = 0 - timeoutCount = 0 - - # 可能的参数 - # wxp://f2f0e4PCkhToyNDT-zfA-Nn6zoAgPKvK9HUl - # https://qr.alipay.com/fkx03165mn5e2hx4gygpx04 - # HTTPS://QR.ALIPAY.COM/FKX01227ZSFRLWLKZSHL9C - # https://payapp.weixin.qq.com/qr/AQEGbDUlzvPBxYKSJst3hENW?t=GAAG#wechat_pay - # https://payapp.weixin.qq.com/qr/AQHoz2ywjCZbBKqDrvUuHDqG?t=GAAG#wechat_pay - # 微信验证 - # 微信为36位长度,只包含-、_、数字和字母,使用正则 - - wxp = re.compile(r'[^\w-]') - wxcode = str(data['wxcode']) - if isKong(wxcode): - wxcode = '' - else: - wxCache1 = re.findall(r"wxp://(.+)",wxcode) - wxCache2 = re.findall(r"https://payapp.weixin.qq.com/qr/(.+)\?t",wxcode) - if wxCache1: - # 第一种 - if(len(wxCache1[0]) == 36): - if not (wxp.search(wxCache1[0])): - hrefCount = hrefCount + 1 + # josn化,应该能当dist用 + dataCache = json.loads(request.form['data']) + # 校验所有用户上传的内容 + data = checkData(dataCache) + if data: + id = data['id'] + res = insertCode(data) + if res: + # 去除里边的id + if data.get('_id'): + data.pop('_id') + try: + filename = '{0}.js'.format(id) + path = os.path.join(datadir, filename) # 将信息写入文件 + f = open(path, 'w', encoding="utf-8") + f.write('{0}{1}'.format('var data = ', data)) + f.close() + except IOError: + return False + return {'errcode': 200, 'id': id} else: - return False - else: - return False - elif wxCache2: - # 第二种 - if(len(wxCache2[0]) == 24): - if not (wxp.search(wxCache2[0])): - hrefCount = hrefCount + 1 - else: - return False - else: - return False + return False else: - # 都不是 - return False - - # openId验证 - # openId为28位长度,只包含-、_、数字和字母,使用正则 - openId = str(data['openId']) - if isKong(openId): - openId = '' - else: - if(len(openId) == 28): - if not (wxp.search(openId)): - openIdCount = 1 - else: return False - else: - return False - - # 支付宝验证 - # 支付宝为23位或22位长度,只有数字和字母,使用isalnum - alcode = str(data['alcode']) - alCache1 = re.findall(r"https://qr.alipay.com/(.+)",alcode) - alCache2 = re.findall(r"HTTPS://QR.ALIPAY.COM/(.+)",alcode) - if isKong(alcode): - alcode = '' - else: - if alCache1: - # 第一种 - if len(alCache1[0]) == 23: - if alCache1[0].isalnum(): - hrefCount = hrefCount + 1 - else: - return False - else: - return False - elif alCache2: - # 第二种 - if len(alCache2[0]) == 22: - if alCache2[0].isalnum(): - hrefCount = hrefCount + 1 - else: - return False - else: - return False - else: - return False - - # QQ验证 - # QQ 一定包含 'qianbao.qq.com',使用正则 - # *!()_-.% 字母 数字 ,正则写不明白了,woc - qqp = re.compile(r'qianbao.qq.com') - qqcode = str(data['qqcode']) - if isKong(qqcode): - qqcode = '' - else: - if(qqp.search(qqcode)): - hrefCount = hrefCount + 1 - else: - return False - - # 用户名验证 - # 正则替换掉引号,$ - username = str(data['username']) - if(not isKong(username)): - username = username.replace('"','') - username = username.replace("'",'') - username = username.replace('$','') - usernameCount = 1 - else: - return False - - # 备注验证 - # 正则替换掉引号,$ - node = str(data['node']) - if(not isKong(node)): - node = node.replace('"','') - node = node.replace("'",'') - node = node.replace('$','') - else: - node = '' - - # 过期时间验证 - timeout = str(data['timeout']) - if(not isKong(timeout)): - if len(timeout) == 13: - timeoutCount = 1 - else: - return False - else: - return False - - if hrefCount >= 2 and usernameCount and openIdCount and timeoutCount: - return {'username': username, 'node': node, 'wxcode': wxcode, 'alcode': alcode, 'qqcode': qqcode, 'openId': openId, 'timeout': timeout, 'create_time':int(time.time())} - else: - return False - -# 创建订单详情 Cache -def createOrderCache(data,params): - data['out_trade_no'] = params['out_trade_no'] - data['create_time'] = int(time.time()) - return data diff --git a/lib/db.py b/lib/db.py index af438cb..148a976 100644 --- a/lib/db.py +++ b/lib/db.py @@ -1,25 +1,10 @@ from pymongo import MongoClient from bson import ObjectId, json_util -# 主环境 -setting = 'test' - # 获取数据集 def col(arg: str = None): - conn = MongoClient('mongodb://yingbo:623910ert@localhost:12236/yingbo') - param = None - if arg: - param = arg - else: - param = setting - if param == 'test': - return conn.yingbo.test - elif param == 'order': - return conn.yingbo.order - elif param == 'cache': - return conn.yingbo.cache - elif param == 'code': - return conn.yingbo.code + conn = MongoClient('mongodb://qrcode:mR6rN4pI0rU6@mongo:27017/qrcode') + return conn.qrcode[arg] # 查找该用户所有信息 def findUser(openid): @@ -28,20 +13,6 @@ def findUser(openid): arr.append(i) return json_util.dumps(arr) -# 查找该二维码所有信息 -def findCode(id): - arr = [] - try: - for i in col('code').find({"_id" : ObjectId(id)}): - arr.append(i) - except Exception as e: - # id不合法 - return False - if(len(arr) == 0): - # 查询无结果 - return False - return json_util.dumps(arr) - # 删除该二维码 def delCode(id): try: @@ -51,70 +22,12 @@ def delCode(id): return False return {'errcode': 200, 'errmsg': 'ok'} -# 用户上传进入缓存表 -def insertOrderCache(data): - try: - col('cache').insert_one(data) - except Exception as e: - # 失败 - return False - return True - -# 用户付款回调 从缓存写进正式表 -def cache2Test(out_trade_no,payjs_order_id): - try: - # 取出缓存表数据 - cache = col('cache').find_one({"out_trade_no" : out_trade_no}) - # 删除缓存表数据 - col('cache').remove({"out_trade_no" : out_trade_no},1) - except Exception as e: - # 失败 - return False - # 判断有没有,去重逻辑 - if cache: - # 向原始数据中添加支付识别码 - cache['payjs_order_id'] = payjs_order_id - # 插入到正式表 - res = col().insert_one(cache) - # 返回插入的正式表id - inserted_id = res.inserted_id - # 放进order表建立 out_trade_no 到 objectId的 映射 - try: - col('order').insert_one({'out_trade_no': out_trade_no, 'inserted_id': inserted_id}) - except Exception as e: - # 失败 - return False - return True - else: - return True - -# 小程序端查询支付结果 -def findOrder(out_trade_no): - arr = [] - try: - for i in col('order').find({"out_trade_no" : out_trade_no}): - arr.append(i) - except Exception as e: - # 失败 - return False - if(len(arr) == 0): - # 查询无结果 - return False - else: - # 删除order中的记录 - try: - col('order').remove({"out_trade_no" : out_trade_no}) - except Exception as e: - # 失败 - return False - return json_util.dumps(arr[0]['inserted_id']) # 用户上传进入主表 def insertCode(data): try: res = col('code').insert_one(data) - inserted_id = res.inserted_id except Exception as e: # 失败 return False - return json_util.dumps(inserted_id) \ No newline at end of file + return True \ No newline at end of file diff --git a/lib/login.py b/lib/login.py index 2153357..6df29b8 100644 --- a/lib/login.py +++ b/lib/login.py @@ -1,8 +1,8 @@ from requests import request import json -def getOpenid(code, where): - if where == 1: +def getOpenid(code, is_mine): + if is_mine == 1: url = 'https://api.weixin.qq.com/sns/jscode2session?appid=wx0df150c438e4c8f0&secret=e43b9f0356a29c8e5b39e79bb27376f1&js_code='+ code +'&grant_type=authorization_code' else: url = 'https://api.weixin.qq.com/sns/jscode2session?appid=wxc4c92bdf93bfa247&secret=488e9b8f1ea69a0cc0bf0e0ed4d572ae&js_code='+ code +'&grant_type=authorization_code' diff --git a/lib/pay.py b/lib/pay.py deleted file mode 100644 index bce868a..0000000 --- a/lib/pay.py +++ /dev/null @@ -1,105 +0,0 @@ -from payjs import PayJS # 也可根据个人习惯选择使用 Payjs/PAYJS/payjs -from payjs import PayJSNotify # 也可根据个人习惯选择使用 PayjsNotify/PAYJSNotify -from signature import get_signature -import random -import time - -MCHID = '1561399401' -KEY = 'C0vy3IlwgWn3TxJD' - -# 初始化 -p = PayJS(MCHID, KEY) - -# 订单查询 -def checkOrder(): - res = p.check_status(payjs_order_id=r.payjs_order_id) - if res: - return res.paid # 是否已支付 - else: - return {'errMsg': s.error_msg, 'err': s} # 错误信息 - -# 回调验证 -def checkNotify(str): - return PayJSNotify(KEY, str) - -# 创建微信小程序 Params -def createOrderParams(totalFee): - body = '收款码合并服务费' # 用户订单标题 - nonce = random.randint(100000,999999) # 随机数 - timestamp = int(time.time()) # 当前时间戳 - outTradeNo = 'QR-WXPay-' + str(timestamp) + '-' + str(nonce) # 商户端订单号 - notifyUrl = 'https://qr.powerrain.cn/notify' # 异步通知地址 - attach = 'from wx' # 异步通知附加数据 - paramsObject = { - 'mchid': MCHID, - 'total_fee': totalFee, - 'out_trade_no': outTradeNo, - 'body': body, - 'attach': attach, - 'notify_url': notifyUrl, - 'nonce': nonce - } - - sign = get_signature(KEY, paramsObject) # MD5签名算法签名 - - paramsObject['sign'] = sign - - return paramsObject - - -# 扫码支付 -# OUT_TRADE_NO = '2017TEST' # 外部订单号(自己的支付系统的订单号,请保证唯一) -# TOTAL_FEE = 1 # 支付金额,单位为分,金额最低 0.01 元最多 10000 元 -# BODY = '测试支付' # 订单标题 -# NOTIFY_URL = 'https://pay.singee.site/empty/' # Notify 网址 -# ATTACH = 'info' # Notify 内容 -# r = p.QRPay(out_trade_no=OUT_TRADE_NO, total_fee=TOTAL_FEE, body=BODY, notify_url=NOTIFY_URL, attach=ATTACH) -# if r: -# print(r.code_url) # 二维码地址(weixin:// 开头,请使用此地址构建二维码) -# print(r.qrcode) # 二维码地址(https:// 开头,为二维码图片的地址) -# print(r.payjs_order_id) # 订单号(PAYJS 的) -# else: -# print(r.STATUS_CODE) # HTTP 请求状态码 -# print(r.ERROR_NO) # 错误码 -# print(r.error_msg) # 错误信息 -# print(r) - -# 构造收银台支付网址(仅构造链接,请使用浏览器 302 到这个网址,无法预检查调用是否成功) -# c = p.get_cashier_url(out_trade_no=OUT_TRADE_NO, total_fee=TOTAL_FEE, body=BODY, callback_url=CALLBACK_URL, notify_url=NOTIFY_URL, attach=ATTACH) -# print(c) - -# JSApi 支付 -# OPENID = '这里填写支付用户的 OpenID' # 支付用户在 PayJS 端的 OpenID,可通过 get_openid 获取 -# j = p.JSApiPay(out_trade_no=OUT_TRADE_NO, total_fee=TOTAL_FEE, openid=OPENID, body=BODY, notify_url=NOTIFY_URL, attach=ATTACH) -# if j: -# print(j.jsapi) # 用于发起支付的支付参数 -# else: -# print(j.STATUS_CODE) # HTTP 请求状态码 -# print(j.ERROR_NO) # 错误码 -# print(j.error_msg) # 错误信息 -# print(j) - -# 刷卡支付 -# AUTH_CODE = '这里填写用户侧 18 位数字' # 用户的支付条码或二维码所对应的数字 -# m = p.MicroPay(out_trade_no=OUT_TRADE_NO, total_fee=TOTAL_FEE, auth_code=AUTH_CODE, body=BODY) -# print(m) - -# 订单关闭 -# def closeOrder(): -# res = p.close(r.payjs_order_id) -# if res: -# return {'errMsg': 'ok', 'errCode': 200} -# else: -# return {'errMsg': res.return_msg, 'errCode': 500} - -# # 订单退款 -# def refundOrder(): -# res = p.refund(r.payjs_order_id) -# if res: -# return {'errMsg': 'ok', 'errCode': 200} -# else: -# return {'errMsg': res.return_msg, 'errCode': 500} - -# # 获取用户 OpenId -# def getOpenId(): -# return p.get_openid(callback_url=CALLBACK_URL) diff --git a/lib/signature.py b/lib/signature.py deleted file mode 100644 index 801b8c9..0000000 --- a/lib/signature.py +++ /dev/null @@ -1,37 +0,0 @@ -from hashlib import md5 -from urllib.parse import urlencode, unquote_plus - -def get_signature(key: str, data: dict): - """ - 签名过程如下: - 0. 忽略已经存在的 sign - 1. 将所有参数名按照字典序排列,并以 "参数1=值1&参数2=值2&参数3=值3" 的形式排序 - 2. 将上面的内容加上 "&key=KEY"(KEY 为设置的商户密钥) - 3. 将组合后的字符串转换为大写 MD5 - - :param key: 商户密钥 - :param data: 要签名的参数字典 - :return: 签名后的字符串 - :rtype: str - """ - d = data.copy() - - # pop 掉 sign 字段 - try: - d.pop('sign') - except KeyError: - pass - - # pop 掉无效字段 - p = sorted([x for x in d.items() if (x[1] or x[1] == 0)], key=lambda x: x[0]) - - p.append(('key', key)) - - p = unquote_plus(urlencode(p)) - - h = md5() - h.update(p.encode()) - - r = h.hexdigest().upper() - - return r \ No newline at end of file diff --git a/lib/utils.py b/lib/utils.py new file mode 100644 index 0000000..907220f --- /dev/null +++ b/lib/utils.py @@ -0,0 +1,157 @@ +import random +import datetime +import time + +# 生成唯一不重名字符串 +def randomId(): + nowTime = datetime.datetime.now().strftime("%Y%m%d%H%M%S") # 生成当前时间 + randomNum = random.randint(0, 100) # 生成的随机整数n,其中0<=n<=100 + if randomNum <= 10: + randomNum = str(0) + str(randomNum) + uniqueNum = str(nowTime) + str(randomNum) + return uniqueNum + +# 判断str转换完是否为空 +def isKong(arg): + if arg == 'None' or arg == '' or arg == None: + return True + else: + return False + +# 上传参数校验 +def checkData(data): + hrefCount = 0 + usernameCount = 0 + openIdCount = 0 + timeoutCount = 0 + + # 可能的参数 + # wxp://f2f0e4PCkhToyNDT-zfA-Nn6zoAgPKvK9HUl + # https://qr.alipay.com/fkx03165mn5e2hx4gygpx04 + # HTTPS://QR.ALIPAY.COM/FKX01227ZSFRLWLKZSHL9C + # https://payapp.weixin.qq.com/qr/AQEGbDUlzvPBxYKSJst3hENW?t=GAAG#wechat_pay + # https://payapp.weixin.qq.com/qr/AQHoz2ywjCZbBKqDrvUuHDqG?t=GAAG#wechat_pay + # 微信验证 + # 微信为36位长度,只包含-、_、数字和字母,使用正则 + + wxp = re.compile(r'[^\w-]') + wxcode = str(data['wxcode']) + if isKong(wxcode): + wxcode = '' + else: + wxCache1 = re.findall(r"wxp://(.+)", wxcode) + wxCache2 = re.findall( + r"https://payapp.weixin.qq.com/qr/(.+)\?t", wxcode) + if wxCache1: + # 第一种 + if(len(wxCache1[0]) == 36): + if not (wxp.search(wxCache1[0])): + hrefCount = hrefCount + 1 + else: + return False + else: + return False + elif wxCache2: + # 第二种 + if(len(wxCache2[0]) == 24): + if not (wxp.search(wxCache2[0])): + hrefCount = hrefCount + 1 + else: + return False + else: + return False + else: + # 都不是 + return False + + # openId验证 + # openId为28位长度,只包含-、_、数字和字母,使用正则 + openId = str(data['openId']) + if isKong(openId): + openId = '' + else: + if(len(openId) == 28): + if not (wxp.search(openId)): + openIdCount = 1 + else: + return False + else: + return False + + # 支付宝验证 + # 支付宝为23位或22位长度,只有数字和字母,使用isalnum + alcode = str(data['alcode']) + alCache1 = re.findall(r"https://qr.alipay.com/(.+)", alcode) + alCache2 = re.findall(r"HTTPS://QR.ALIPAY.COM/(.+)", alcode) + if isKong(alcode): + alcode = '' + else: + if alCache1: + # 第一种 + if len(alCache1[0]) == 23: + if alCache1[0].isalnum(): + hrefCount = hrefCount + 1 + else: + return False + else: + return False + elif alCache2: + # 第二种 + if len(alCache2[0]) == 22: + if alCache2[0].isalnum(): + hrefCount = hrefCount + 1 + else: + return False + else: + return False + else: + return False + + # QQ验证 + # QQ 一定包含 'qianbao.qq.com',使用正则 + # *!()_-.% 字母 数字 ,正则写不明白了,woc + qqp = re.compile(r'qianbao.qq.com') + qqcode = str(data['qqcode']) + if isKong(qqcode): + qqcode = '' + else: + if(qqp.search(qqcode)): + hrefCount = hrefCount + 1 + else: + return False + + # 用户名验证 + # 正则替换掉引号,$ + username = str(data['username']) + if(not isKong(username)): + username = username.replace('"', '') + username = username.replace("'", '') + username = username.replace('$', '') + usernameCount = 1 + else: + return False + + # 备注验证 + # 正则替换掉引号,$ + node = str(data['node']) + if(not isKong(node)): + node = node.replace('"', '') + node = node.replace("'", '') + node = node.replace('$', '') + else: + node = '' + + # 过期时间验证 + timeout = str(data['timeout']) + if(not isKong(timeout)): + if len(timeout) == 13: + timeoutCount = 1 + else: + return False + else: + return False + + if hrefCount >= 2 and usernameCount and openIdCount and timeoutCount: + return {'username': username, 'node': node, 'wxcode': wxcode, 'alcode': alcode, 'qqcode': qqcode, 'openId': openId, 'timeout': timeout, 'create_time': int(time.time()), 'id': randomId()} + else: + return False \ No newline at end of file diff --git a/qr/qrcode.html b/qr/qrcode.html index 5d9af28..c6814f9 100644 --- a/qr/qrcode.html +++ b/qr/qrcode.html @@ -32,14 +32,14 @@ var id = GetQueryString("id") // 不合法id的处理 if(id == null || id.search(/\W+/) != -1 || id.length != 24) { - window.location.replace("https://qr.powerrain.cn/qr/410.html"); + window.location.replace("https://qr.lacus.site/qr/410.html"); } var data = document.createElement("script"); - data.src = `https://qr.powerrain.cn/data/${id}.js` + data.src = `https://qr.lacus.site/data/${id}.js` var s = document.getElementsByTagName("script")[0]; // 加载失败处理,默认失败时间是2秒 var timer = setTimeout(function(){ - window.location.replace("https://qr.powerrain.cn/qr/500.html"); + window.location.replace("https://qr.lacus.site/qr/500.html"); },2000) data.onload = function(){ clearTimeout(timer) @@ -59,12 +59,12 @@ qrcodeApi: "http://qr.topscan.com/api.php?text=" } - var bgs = ['./img/bg1.jpg', - './img/bg2.jpg', - './img/bg3.jpg', - './img/bg4.jpg', - './img/bg5.jpg', - './img/bg6.jpg',] + var bgs = ['https://qr.lacus.site/qr/img/bg1.jpg', + 'https://qr.lacus.site/qr/img/bg2.jpg', + 'https://qr.lacus.site/qr/img/bg3.jpg', + 'https://qr.lacus.site/qr/img/bg4.jpg', + 'https://qr.lacus.site/qr/img/bg5.jpg', + 'https://qr.lacus.site/qr/img/bg6.jpg',] //初始化 function init() { @@ -81,7 +81,7 @@ var timeout = parseInt(data.timeout) timeout = new Date(timeout) var now = new Date() - if (timeout - now <= 0) window.location.replace("https://qr.powerrain.cn/qr/410.html"); + if (timeout - now <= 0) window.location.replace("https://qr.lacus.site/qr/410.html"); // 换背景 ele('bg').src = bgs[Math.floor(Math.random() * bgs.length)] setting.id = data._id.$oid @@ -138,7 +138,7 @@ ele("wq_b").setAttribute("class", "wx_b"); ele("title").innerHTML = "推荐使用微信支付"; ele("user1").innerHTML = setting.username; - ele("wq_pay").setAttribute("src", "./img/sprite3.png"); + ele("wq_pay").setAttribute("src", "https://qr.lacus.site/qr/img/sprite3.png"); } else { //木有微信的链接 noSupport("微信", 1) @@ -150,7 +150,7 @@ ele("wq_b").setAttribute("class", "qq_b"); ele("title").innerHTML = "推荐使用QQ支付"; ele("user1").innerHTML = setting.username; - ele("wq_pay").setAttribute("src", "./img/sprite2.png"); + ele("wq_pay").setAttribute("src", "https://qr.lacus.site/qr/img/sprite2.png"); } else { //木有QQ的链接 noSupport("QQ", 1); @@ -317,7 +317,7 @@ .all .imageBox>div { height: 50px; width: 52px; - background-image: url('./img/sprite1.png'); + background-image: url('https://qr.lacus.site/qr/img/sprite1.png'); background-size: cover; } diff --git a/qrcodeMe.py b/qrcode.py similarity index 57% rename from qrcodeMe.py rename to qrcode.py index b26f3e5..860efcd 100644 --- a/qrcodeMe.py +++ b/qrcode.py @@ -3,9 +3,11 @@ sys.path.append('./lib') import os from flask import Flask, escape, url_for, request, render_template, redirect, abort, send_from_directory -from allFunction import manageLogin, findQR, flash, delQR, manageNotify, createOrder, checkOrder, addQR - +from allFunction import manageLogin, flash, delQR, addQR +from flask_qrcode import QRcode + app = Flask(__name__) +QRcode(app) if __name__ == '__main__': app.run() @@ -19,15 +21,6 @@ def login(): else: abort(400) -# # 用户扫描二维码 -# @app.route('/qr',methods=['GET']) -# def qr(): -# res = findQR(request) -# if(res): -# return render_template('qrcode.html',data = res) -# else: -# abort(410) - # 小程序刷新用户信息 @app.route('/reflash',methods=['POST']) def reflash(): @@ -55,36 +48,16 @@ def addQRCode(): else: abort(400) -# 创建新的订单(暂时废弃) -# @app.route('/newOrder',methods=['POST']) -# def newOrder(): -# res = createOrder(request) -# if(res): -# return res -# else: -# abort(400) - -# 处理订单异步通知(暂时废弃) -# @app.route('/notify',methods=['POST']) -# def notify(): -# manageNotify(request) -# return 'ok' - -# 小程序查询订单状态(暂时废弃) -# @app.route('/checkOrder',methods=['POST']) -# def check(): -# res = checkOrder(request) -# print(res) -# if res: -# return res -# else: -# abort(500) +# 生成二维码 +@app.route('/generate',methods=['GET']) +def generate(): + text = request.args.get("text") + return qrcode(text) # 控制小程序是否显示“最佳案例” @app.route('/config', methods=['post']) def config(): - return {'errcode': 200, 'showBest': 'true'} - + return {'errcode': 200, 'showBest': 'false'} # 图标 @app.route('/favicon.ico') @@ -110,7 +83,4 @@ def page_not_found(e): @app.errorhandler(410) def page_not_found(e): - return render_template('410.html'), 500 - -# 目前的安全模式依赖于限制post访问,非对称加密校验,对所有内容进行规则审查, -# 主要还是防止有人恶意访问,等到写密码本的时候尝试模拟ssl加密模式 + return render_template('410.html'), 500 \ No newline at end of file diff --git a/qrcodeLi.py b/qrcodeLi.py deleted file mode 100644 index 801f218..0000000 --- a/qrcodeLi.py +++ /dev/null @@ -1,116 +0,0 @@ -import sys -sys.path.append('./lib') - -import os -from flask import Flask, escape, url_for, request, render_template, redirect, abort, send_from_directory -from allFunction import manageLogin, findQR, flash, delQR, manageNotify, createOrder, checkOrder, addQR - -app = Flask(__name__) - -if __name__ == '__main__': - app.run() - -# 用户小程序登录 -@app.route('/li/login',methods=['POST']) -def login(): - res = manageLogin(request, 2) - if(res): - return res - else: - abort(400) - -# # 用户扫描二维码 -# @app.route('/qr',methods=['GET']) -# def qr(): -# res = findQR(request) -# if(res): -# return render_template('qrcode.html',data = res) -# else: -# abort(410) - -# 小程序刷新用户信息 -@app.route('/li/reflash',methods=['POST']) -def reflash(): - res = flash(request) - if(res): - return res - else: - abort(400) - -# 用户删除二维码 -@app.route('/li/del',methods=['POST']) -def delQRCode(): - res = delQR(request) - if(res): - return res - else: - abort(400) - -# 用户添加二维码 -@app.route('/li/add',methods=['POST']) -def addQRCode(): - res = addQR(request) - if(res): - return res - else: - abort(400) - -# 创建新的订单(暂时废弃) -# @app.route('/newOrder',methods=['POST']) -# def newOrder(): -# res = createOrder(request) -# if(res): -# return res -# else: -# abort(400) - -# 处理订单异步通知(暂时废弃) -# @app.route('/notify',methods=['POST']) -# def notify(): -# manageNotify(request) -# return 'ok' - -# 小程序查询订单状态(暂时废弃) -# @app.route('/checkOrder',methods=['POST']) -# def check(): -# res = checkOrder(request) -# print(res) -# if res: -# return res -# else: -# abort(500) - -# 控制小程序是否显示“最佳案例” -@app.route('/li/config', methods=['post']) -def config(): - return {'errcode': 200, 'showBest': 'true'} - - -# 图标 -@app.route('/li/favicon.ico') -def favicon(): - return send_from_directory(os.path.join(app.root_path, 'static'),'favicon.ico', mimetype='image/vnd.microsoft.icon') - -@app.route('/li/') -def notDefind(): - abort(404) - -# 二维码查询失败重定向, 404 -@app.errorhandler(404) -def page_not_found(e): - return render_template('404.html'), 404 - -@app.errorhandler(400) -def page_not_found(e): - return render_template('400.html'), 400 - -@app.errorhandler(500) -def page_not_found(e): - return render_template('500.html'), 500 - -@app.errorhandler(410) -def page_not_found(e): - return render_template('410.html'), 500 - -# 目前的安全模式依赖于限制post访问,非对称加密校验,对所有内容进行规则审查, -# 主要还是防止有人恶意访问,等到写密码本的时候尝试模拟ssl加密模式