在上一篇文章中,我们用postman导入了数字货币交易所的API,进行了本地化的参数设置后,使得我们可以方便快捷的使用这些交易所提供的API进行数据探索。但其中大部分的接口是需要进行数字签名认证的,虽然postman默认提供了多种认证方式,但对于数字货币交易所这种需要定制化header,并对内容进行加密以生成签名的方式不是默认支持的。所以,我们在今天的文章来看看postman如何做数字认证的签名
这里不一一介绍了,具体可以查看官网。这里重点说一下Inherit auth from parent
,因为postman里面管理request或者说是API是有层级结构的,即 collection
-> folder
-> request
。
当在collection
配置了认证方式后,folder
可选择继承collection
的认证方式,方法是将其认证方式设置为Inherit auth from parent
。
同理,request
也可继承folder
和collection
。
folder
和 collection
进行统一的认证配置因此,在我们整理数字货币交易所的接口时,我们可以对需要用户认证的接口进行统一的认证处理:
但很可惜,虽然postman提供了方式可以对folder
和collection
进行统一的认证配置,但因为交易所的数字签名认证不在支持访问之内,所以不能直接采用上文说的方式。
我们现在简单回顾一下交易所的签名方式
securityDefinitions":{"apiKey":{"type":"apiKey","in":"header","name":"api-key"},"apiSignature":{"type":"apiKey","in":"header","name":"api-signature"},"apiExpires":{"type":"apiKey","in":"header","name":"api-expires"}},"security":[{"apiKey":[],"apiSignature":[],"apiExpires":[]}]}
一般来说都是3个值需要配置:
api-secret
是一个pair对,一一对应,知道了api-key
即可查询到api-secret
api-secret
和message
一起生成的签名,这里的message
一般包括:
举例:'POST/api/v1/order1416993995705{"symbol":"XBTZ14","quantity":1,"price":395.01}'
,如果是GET
,没有body的话,则data为''
api-signature
的生成规则一般为:
hmac_sha256
,输出值需转化为 hex
我在上一篇文章使用nodejs/python生成signature 中,已经介绍过如何生成数字签名。现在我们要做的是为每条需要认证的消息加上三个header
: api-key
,api-expires
和api-signature
, 并且,其中的api-expires
和api-signature
是需要实时计算的。
这里以api-signature
举例:
这个问题在社区里面都提了一年多了,并且很多人都提了这个需求,很难想象postman的团队居然一年都搞不定,自从这个团队多了很多印度人之后,感觉堕落了。。。
),需要设置一个preset:因为api-signature
中的nonce和data是动态的,因此需要动态获取,然后计算。
计算的方式是:
verb + path + str(nonce) + data
这里,我们需要了解pre-request script和Postman Sandbox API
这是pre-request script的运行环境,pre-request script可以获取该sanbox里面定义的global变量和提供的API。
众所周知的,chrome是一个node程序,因此,Postman Sandbox内也提供了部分内建的node library module,以require
的方式获取,他们包括:
这真的很贴心???,因为大部分场景够用了!???
pm 对象含括了所有与script只想相关的信息,并且运行使用者访问将要被发送的request以及收到的resonse的副本 (注意,这里是副本,即你无法通过pm改变request的内容,也即是无法动态的增加header)。同时也允许使用者对env变量或者global变量进行读取和设置。(如果有必要我会针对这个单独写一篇文章)
这里,我们主要关注读取request的内容,因为我们需要读取body值来做signature。
我们可以以如下方式访问request:
pm.request.url:Url
pm.request.headers:HeaderList
通过console的方式把pm.request对象打出来,可以看到具体包含的子属性有:
代码贴上:
var CryptoJS = require('crypto-js')
var apiSecret = pm.environment.get("apiSecret");
var expires = Date.now() + 25000
expires = parseInt(expires / 1000)
pm.environment.set("expires", expires);
var theUrl = pm.request.url.getPath() + '?' + pm.request.url.getQueryString({ignoreDisabled:true})
var message = pm.request.method+theUrl+expires+pm.request.body.raw;
var signature = CryptoJS.enc.Hex.stringify(CryptoJS.HmacSHA256(message,apiSecret))
pm.environment.set("signature", signature);
以下例子中,所有order相关的接口是需要签名认证的,所以配置统一的pre-request script和header Presets
其实使用header Presets并不是一个特别方便的解决方案,因为得需要点下鼠标,配置并保存。期望postman团队更多的倾听来自用户的反馈,产品经理要做好优先级排序的工作。