嗨,大家好,我是小白,好久没写博客了,最近公司搞什么python的接口测试,心里一阵狂喜,在公司上百个接口里拿出一个主要接口一顿乱搞,好在搞通了

但是在这过程中也碰到了好多的问题,决定将问题分享出来能够对你们提供一丝丝的帮助!

工具:pycharm+requests+python3+fiddler

我暂时将我使用的接口称为A接口

第一步:

首先我们手工发起一笔成功的A接口,

返回的json字符串:{"requestId":"20190220095236495","result":"00000","signature":"******","sum":"0.03"}

从字符串中的result我们知道返回成功了,signature为对返回结果进行了签名,使用到的是MD5签名

第二步:

查看fiddler,在Inspectors-Raw下边提炼出我们想要的一些信息

python 以接口的形式对外发布程序 python中接口_返回结果

从图中我们知道这个请求为POST请求,content-Type:application/x-www-form-urlencoded,encoding:GBK  保存这些信息

第三步:

打开pycharm,在里边通过字典设置A接口的各个参数,由于输入参数signature是对所有参数进行MD5签名,所以我们设置为空值,

对字典的value值进行for循环拼接,并调用MD5签名方法进行签名,方法如下:

python 以接口的形式对外发布程序 python中接口_python 以接口的形式对外发布程序_02

然后我们再将返回的enc_res回传到字典的键signature所对应的值

1) 设置A接口发起请求的url

2) 设置字典headers(直接从fiddler抓包的raw数据里copy过来),如下:

python 以接口的形式对外发布程序 python中接口_json_03

 3) 从抓包我们知道content-Type:application/x-www-form-urlencoded,所以发起post请求的参数为data而不是json



requests.post(url=url,data=payload,headers=headers)



 通过返回结果的status为200我们知道请求成功了,但是返回的result是一个错误码,通过日志我们找到了原因如下:

python 以接口的形式对外发布程序 python中接口_python_04

可以看出accountName参数传到后台为乱码,因为pycharm里边传过去的中文,编码都是UTF-8的,而后台编码从抓包我们可以看到是GBK的形式,

所以我们需要改变一下这个参数编码格式如图:

python 以接口的形式对外发布程序 python中接口_返回结果_05

因为A接口输入参数有一个MD5的签名参数,所以中文参数的这段编码要放在输入参数签名之后,然后回传进行覆盖,进行post请求

再试一遍,我们发现返回结果成功了,并且我们对返回的参数再次进行调用MD5签名校验

 

python 以接口的形式对外发布程序 python中接口_json_06

 

没有看懂的小伙伴可以留言,我们可以一起交流讨论,哈哈,我是小白,欢迎阅读!

 源码分享一下,写的没什么层次,还请多多批评:

# -*- coding:utf-8 -*-
#autor :xiaobai
import requests
from requests.cookies import RequestsCookieJar
import json
import hmac
import hashlib
import time
import random
####################设置Key值##############

def hashstring(to_enc,ekey):
    enc_res = hmac.new(ekey.encode(), to_enc.encode(), hashlib.md5).hexdigest()
    # print(enc_res)
    return enc_res

if __name__=='__main__':
    print("开始进行**测试: ")
    url='http://**********'
    #设置随机值作为入参id
    id = []
    id = ''.join(str(i) for i in random.sample(range(0, 9), 2))  # sample(seq, n) 从序列seq中选择n个随机且独立的元素;
    CurrentTime = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
    requestid=CurrentTime+id
    #请求参数
    payload={'requestId':'',
          'merchantCode':'',
          'transferType':'',
          'transToMerCode':'',
          'transToMerName':'',
          'unionBankNum':'',
          'openBankName':'',
          'openBankProvince':'',
          'openBankCity':'',
          'sum':'0.03',
          'accountType':'1',
          'accountName':'***',
          'bankCode':'***',
          'bankAccount':'*******',
          'reason':'1555',
          'noticeUrl':'**********',
          'refundNoticeUrl':'*************',
          'transferPayType':'*',
          'signature':''
             }
    payload['requestId']=requestid
    #初始化字符串并进行加密拼接
    to_enc=''
    ekey='CSSH_KEY'
    for i in payload:
        to_enc=to_enc+payload[i]
    # print(to_enc)
    payload['signature'] = hashstring(to_enc, ekey)

    '''将中文进行GBK转化'''
    str='***'  #这个字符串与字典里accountName对应value一致
strGBK=str.encode('GBK')
    '''转化完的中文回传到字典中'''
    payload['accountName']=strGBK
    headers={
            'Connection':'keep-alive',
            'Content-Length':'543',
            'Cache-Control':'max-age=0',
            'Origin':'http://**********',
            'Upgrade-Insecure-Requests':'1',
            'Content-Type':'application/x-www-form-urlencoded',
            'User-Agent':'**************************************************',
            'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
            'Referer':'******************',
            'Accept-Encoding':'gzip, deflate, br',
            'Accept-Language':'zh-CN,zh;q=0.9',
        }
    s=requests.post(url=url,data=payload,headers=headers)
    print(s.text)
    print("status:",s.status_code)
    print("****************************************************")
    print("开始进行返回结果验证签名: ")
    '''返回结果进行验签'''
    ResultDict=s.json()
    synchronizationStr=ResultDict['requestId'] + ResultDict['result'] + ResultDict['sum']
    signature11=hashstring(synchronizationStr, ekey)
    try:
        if(ResultDict['result']=='00000' and signature11==ResultDict['signature']):
            print("                    恭喜你,同步返回验签成功")
        else:
            print("                    result错误码:", ResultDict['result'])
    except BaseException as msg:
        print(msg)
    finally:
        print("                    **处理完毕")
    print("****************************************************")