经过一天的调试,终于完成了对京东联盟API接口的调试,完成的接口的验签,接口调用,下面是用python实现的,做个简单的记录,供有兴趣的小伙伴参考学习
一、应用创建
首先我们登录京东联盟,进入到控制台,创建应用,应用创建完成以后我们才能拿到接口验签最重要的两个参数值,appKey和App Secret,下图是我创建的一个应用
到这里,假设你已经创建完成的应用,下面我们开始进入正题,api对接
二、验签参数详解
接口的验签是调用一个接口最重要的一步,让我们看下如何实现,才能避免少踩坑,具体的详细文档可以参考【传送阵】,具体步骤主要分为以下5步:
- 验签参数
- 参数的排序
- 拼接参数
- 加密
- 小写转大写
1、验签参数
这个参数除了基本的必填参数以外,还保存业务接口传的参数
params = {
# API接口名称
"method": 'jd.union.open.order.query',
# 第一步创建应用后生成的app key
"app_key": '***************',
# 时间戳 格式为yyyy-MM-dd HH:mm:ss,时区为GMT+8
"timestamp": '2021-01-01 12:00:00',
# 响应格式,暂时只支持json
"format": 'json',
# API协议版本,一般为1.0
"v": '1.0'
# 签名的摘要算法,暂时只支持md5
"sign_method": 'md5',
# API输入参数签名结果
"sign": '************'
}
# 下面进行参数的合并
# 业务接口参数都传到360buy_param_json这个字段上,这个是重点,要不验签失败
api_query = { **params, "360buy_param_json": query}
以上参数都是必填字段,还有一个字段access_token非必填,这里不做讲解,具体可以查看文档
2、参数排序
为什么要排序呢 ,咱也不知道,排序就排序吧,按照字母abcd顺序排就行了,记住是按照对象的Key排序,不是value,下面看代码,在python中是如何排序的,我也没找到什么好的方法
# 将所有请求参数按照字母先后顺序排列
#reverse: true 倒序,false 正序
params_key_sort = sorted(api_query, key=str.lower, reverse=False)
3、参数拼接
拼接参数的格式是: secretkey+key+value+key+value…+secretkey
这里有个需要注意的地方,如果参数值是dict,记得要转成字符串(也算一个小坑吧)
params_key_sort = sorted(api_query, key=str.lower, reverse=False)
sign = secretkey
for i in params_key_sort:
# 这里对所有value进行了处理,可以做下判断
sign = sign+i+str(api_query[i])
sign = sign+secretkey
4、加密
md5加密使用hashlib这个库,长度是32位,这一步没什么坑,调用方法就行了
import hashlib
# MD5加密
hl = hashlib.md5()
hl.update(sign.encode(encoding='utf-8'))
sign = hl.hexdigest()
5、小写转大写
这里小写转大写是对加密后的字符串进行一个转换的
sign = sign.upper()
三、验签完整代码登场
"""
京东联盟api签名
"""
import time
import hashlib
# 应用的appKey
appKey = "dd68*******8a7f11"
# 应用的密匙
secretkey = "84a******de141"
def sign_method(method, data):
# 时间戳 格式YYYY-MM-DD HH:mm:ss
timestamp = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
# 验签参数
params = {
"method": method, # API接口名称
"app_key": appKey,
"timestamp": timestamp,
"format": "json",
"v": "1.0",
"sign_method": "md5"
}
# 合并基本参数与应用参数
api_query = {**params, "360buy_param_json": data}
# 将所有请求参数按照字母先后顺序排列
params_key_sort = sorted(api_query, key=str.lower, reverse=False)
print('排序后的参数:', params_key)
# 验签的字符串,首尾需要加secretkey
sign = secretkey
for i in params_key_sort:
sign = sign+i+str(api_query[i])
sign = sign+secretkey
print('sign:', sign)
# MD5加密,并且小写字母需要大写
hl = hashlib.md5()
hl.update(sign.encode(encoding='utf-8'))
sign = hl.hexdigest()
api_query['sign'] = sign.upper()
# 返回调用api接口所有参数
return api_query
四、请求接口
新版接口地址:https://api.jd.com/routerjson,这里我们就使用requests库去请求
# coding: utf-8
from urllib.parse import urlencode
import requests
def request(data):
try:
"""响应头设置"""
headers = {"Content-Type": "application/x-www-form-urlencoded"}
# 将参数转换成form形式也就是: key=value&key=value...
params = urlencode(data)
print('请求参数:', params)
res = requests.post("https://api.jd.com/routerjson", data=params, headers=headers)
return res.json()
except request.HTTPError as e:
print("Error code: ", e.code)
return e.code
五、接口server开发
1、项目创建
到这里最重要的两部分已经算是完工了,通过postman调用只要验签通过,就相当于已经完成了90%的工作,下面就是接口的开发,这里为了方便,我们使用flask这个web框架去搭建我们的后台服务。可以使用PyCharm工具自动去生成,在新建项目的时候自己选择
2、接口开发
由于之前好多人问关于这部分的参数有问题,作为一名前端开发,今天抽时间正好完善下关于整个接口的调用,以及参数如何传递。这里我们就以"京粉精选商品查询接口为例",下面是我创建的一个目录结构,可以自行调整
# api/jinfen_query.py
from api.sign import sign_method
from api.request import request
def jinfen_query(data):
query = sign_method(data['method'], data['query'])
res = request('https://api.jd.com/routerjson', query)
return res
3、接口路由
from flask import Flask, request
from api.jingfen_query import jinfen_query
import json
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
# 参数解释
# method: API接口名称
# query: 业务参数
@app.route('/jinfen', methods=["POST"])
def jinfen():
# 获取接口参数
data = request.get_data();
data = json.loads(data)
res = jinfen_query(data)
# 根据API名称,转换相应字符串,获取接口返回数据
res_type = data['method'].replace('.', '_') + '_responce'
jingfen_data = res[res_type]
if jingfen_data:
if jingfen_data['code'] == '0':
return jingfen_data['queryResult']
else:
return '系统错误'
if __name__ == '__main__':
app.run()
到这里我们的代码就写的差不多了,下面让我们用postman测试下接口数据返回的情况,以及入参的传递,下面分别对两个api的调用及返回做了测试,如果有什么问题,欢迎各位猿友指正;
1、猜你喜欢商品推荐 测试
2、京粉精选商品查询接口 测试
六、总结
写到这里基本算完工了,感兴趣的小朋友们可以自己实现哈,没事的时候练练手,其实挺好玩的,刚开始写的主要卡在了验签上,总是提示app_key为空,后来各种查,各种找,才发现在验签参数的问题,也就是360buy_param_json这个东西在搞鬼,开始业务参数是直接传的,没有赋值到360buy_param_json上面,手指头都磨秃噜皮了(开个玩笑)