上海古都建筑设计集团,上海办公室装修设计公司,上海装修公司高质量的内容分享社区,上海装修公司我们不是内容生产者,我们只是上海办公室装修设计公司内容的搬运工平台

postman之接口参数签名(js接口HMAC-SHA256签名)

guduadmin251月前

文章目录

  • postman之接口参数签名(js接口签名)
    • 一、需求背景
    • 二、签名生成规则
    • 三、postman js接口签名步骤
      • 1. postman设置全局、或环境参数
      • 2. 配置Pre-request Scripts脚本
      • 四、Pre-request Scripts脚本 常见工作整理
        • 1. js获取unix时间戳
        • 2. body json字符串进行md5运算
        • 3. JS字符串拼接
        • 4. 哈希签名 HMAC-SHA256
          • 使用CryptoJS的hmac
          • 5. PostMan 在请求中自动添加Header
          • 6. 使用PM对象访问与操作请求参数(pm.request.*)
          • 7. JS字符串拼接/连接
          • 8. JavaScript判断变量是否为空
          • 参考

            postman之接口参数签名(js接口签名)

            一、需求背景

            在对外发布的接口中,基本上都会涉及到对接口字段进行签名加密,以防篡改。

            后端接口为了避免参数被篡改,有参数签名的校验,为方便使用postman测试接口,可在postman设置自动签名。

            Postman每发起一个请求之前,都可以选择执行一段pre-request script。这恰恰给了我们机会在请求发起之前生成我们需要的数据。

            二、签名生成规则

            不同项目签名规则不同。不过核心思路就是把你的请求需要防止篡改的部分进行HMAC-SHA256签名。

            例如如下的待签名数据,使用 | 分隔 拼接你将来要签名的数据

            method|url|timestamp|appKey|MD5(body)
            

            三、postman js接口签名步骤

            1. postman设置全局、或环境参数

            postman 配置全局参数,设置 appKey、appSecret等全局参数

            postman之接口参数签名(js接口HMAC-SHA256签名),在这里插入图片描述,第1张postman之接口参数签名(js接口HMAC-SHA256签名),在这里插入图片描述,第2张

            2. 配置Pre-request Scripts脚本

            postman关键pre-script官方文档:https://learning.postman.com/docs/writing-scripts/script-references/postman-sandbox-api-reference/#scripting-with-request-info

            配置脚本,编辑collection,选择Pre-request Scripts,输入脚本

            完成以下能力

            • 获取签名参数
            • 生成签名
            • 赋值到指定heaher中

              demo1:

              var appKey = pm.environment.get("appKey");
              var appSecret = pm.environment.get("appSecret");
              var queryParam = pm.request.url.query.members;
              var timestamp = new Date().getTime();
               
              let param = JSON.parse("{}");
               
              for (let i in queryParam){
                  param[queryParam[i].key] = queryParam[i].value;
              }
              param['timestamp'] = timestamp;
              var keys = [];
              for (let k in param){
                  if (k == 'sign'){
                      continue;
                  }
                  keys.push(k);
              }
              //排序
              keys.sort();
               
              //取value
              var sign = '';
              sign = sign + appSecret;
              for (let k of keys){
                  sign = sign+ (k + '' + encodeURIComponent(param[k]));
              }
              sign = sign+appSecret;
              console.log(sign);
              sign = CryptoJS.MD5(sign).toString();
              console.log(sign);
              pm.environment.set('sign',sign);
              pm.environment.set('timestamp',timestamp);
              pm.environment.set('appKey',encodeURIComponent(appKey));
              
              //获取url的path部分
              getUrlRelativePath:function(url){
                  var arrUrl = url.split("//");
                  var start = arrUrl[1].indexOf("/");
                  var end=arrUrl[1].indexOf("?");
                  var relUrl = arrUrl[1].substring(start,end);//stop省略,截取从start开始到结尾的所有字符
                  console.log(relUrl);
                  return relUrl;
              }
              

              demo2:

              var appKey = pm.environment.get("appKey");
              var appSecret = pm.environment.get("appSecret");
              var method = pm.request.method
              console.log('method:', method)
              var url = pm.request.url.getPath()
              console.log('url:', url)
              var queryParam = pm.request.url.query.members;
              console.log('queryParam:', queryParam)
              // js获取unix时间戳 getTime()返回数值的单位是毫秒
              var timestamp = new Date().getTime();
              console.log('timestamp:', timestamp)
              var body = pm.request.body.raw;
              console.log('body:', body)
              var bodyMd5= CryptoJS.MD5(body).toString();
              console.log('bodyMd5:', bodyMd5)
              // // 序列化
              // var json="";
              // try {
              //   json = JSON.parse(body); //序列化JSON BODY
              //   param = json;
              // }catch(err){
              //   //BODY不是JSON格式
              //   console.log("json data error");
              // }
              // console.log(json);
              // var jsonStringify = JSON.stringify(param).toString();
              // console.log('jsonStringify:',jsonStringify);
              // var bodyStrMd5= CryptoJS.MD5(jsonStringify).toString();
              // console.log('bodyStrMd5:', bodyStrMd5)
              tonce = new Date().getTime() * 1000
              console.log('tonce:', tonce)
              //method|url|tonce|accesskey|other|MD5(body)
              var signatureRawData = `${method}|${url}|${tonce}|${appKey}|${bodyMd5}`
              console.log('signatureRawData:', signatureRawData)
              //生成哈希签名
              var signature = CryptoJS.enc.Utf8.parse(signatureRawData);
              //var secret_bytes = CryptoJS.enc.Base64.parse(appSecret);
              var secret_bytes = CryptoJS.enc.Utf8.parse(appSecret);
              var signatureBytes = CryptoJS.HmacSHA256(signature,secret_bytes)
              console.log('signatureBytes:', signatureBytes)
              var signStr = signatureBytes.toString()
              console.log('signStr:', signStr)
              var signatureRawData = `${method}|${url}|${tonce}|${appKey}|${bodyMd5}`
              //认证头编码创建
              var authorizationStr = `${appKey}:${signStr}`
              console.log('authorizationStr:', authorizationStr)
              var requestSignatureBase64String = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(authorizationStr));
              console.log('requestSignatureBase64String:', requestSignatureBase64String)
              //设置到postman环境变量中,postman  hearder引入该变量
              pm.environment.set("signature",requestSignatureBase64String)
              pm.request.headers.add({
                  key: 'Authorization',
                  value: requestSignatureBase64String
              });
              pm.request.headers.add({
                  key: 'tonce',
                  value: tonce
              });
              

              四、Pre-request Scripts脚本 常见工作整理

              1. js获取unix时间戳

              如何在 JavaScript 中获取 UNIX 时间戳

              参考URL: https://blog.csdn.net/allway2/article/details/122558429

              UNIX 时间戳是一个整数值,表示自UNIX 纪元于 1970 年 1 月 1 日 00:00:00 UTC以来经过的秒数。简而言之,这是一种将时间跟踪为运行总秒数的方法。因此,UNIX 时间戳只是特定日期和 UNIX 纪元之间的秒数。

              JavaScriptDate对象提供了几种处理日期和时间的方法。now()您可以通过调用对象上的函数来获取当前时间戳,Date如下所示:

              const timestamp = new Date().getTime()
              

              此方法以毫秒为单位返回当前的 UTC 时间戳。

              getTime()返回数值的单位是毫秒

              微秒级时间戳,我们这里直接乘以1000,因为js找不到获取微秒级的方法,谁知道可以评论区留言。这里我们乘以1000凑成微秒级的位数。

              2. body json字符串进行md5运算

              CryptoJS是一个前端加密的JS库,它可以进行MD5,AES等进行加密

              这边直接使用CryptoJS.MD5即可

              var body=pm.request.body.raw;
              // 序列化
              var json="";
              try {
                json = JSON.parse(body); //序列化JSON BODY
                param = json;
              }catch(err){
                //BODY不是JSON格式
                console.log("json data error");
              }
              console.log(json);
              var jsonStr = JSON.stringify(param).toString();
              sign = CryptoJS.MD5(jsonStr).toString();
              

              这里是对body的json解析出来后,然后 JSON.stringify 处理后,进行md5.

              当然你也可以直接对body的原始内容,进行md5

              var body=pm.request.body.raw;
              sign = CryptoJS.MD5(body).toString();
              

              3. JS字符串拼接

              JS字符串拼接的几种方式

              参考URL: https://huaweicloud.csdn.net/63a568aeb878a54545946b76.html

              在 JavaScript 中,使用字符串连接有 几 种方式:连接符(+)、反引号(`)、join()、concat()。

              • 使用模板字符串,以反引号( ` )标识

                ES6中新增的字符串方法,可以配合反单引号完成拼接字符串的功能

                反单引号怎么打出来:将输入法调整为英文输入法,单击键盘上数字键1左边的按键。

                用法:

                1: 定义需要拼接进去的字符串变量

                2: 将字符串变量用${}包起来,再写到需要拼接的地方

                let a = 'java'
                let b = `hello ${a}script`
                

                接口签名demo:

                对如下数据进行拼接,将来进行签名。

                method|url|timestamp|appKey|MD5(body)
                
                var sign = `${method}|${url}|${timestamp}|${appKey}|${bodyMd5}`
                

                4. 哈希签名 HMAC-SHA256

                HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code)的缩写,由H.Krawezyk,M.Bellare,R.Canetti于1996年提出的一种基于Hash函数和密钥进行消息认证的方法, 并于1997年作为RFC2104被公布,并在IPSec和其他网络协议(如SSL)中得以广泛应用,现在已经成为事实上的Internet安全标准。它可以与任何迭代散列函数捆绑使用。

                HMAC算法利用哈希运算,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。

                使用SHA-1、SHA-224、SHA-256、SHA-384、SHA-512所构造的HMAC,分别称为HMAC-SHA1、HMAC-SHA-224、HMAC-SHA-256、HMAC-SHA-384、HMAC-SHA-512。

                postman的脚本库中CryptoJS是支持各种算法的加密,包括HMACSHA256。

                CryptoJS 是一个使用 JavaScript 实现的加密算法库

                它支持的算法包含:

                • Base64
                • MD5
                • SHA-1 和 SHA-256
                • AES
                • Rabbit
                • MARC4
                • HMAC、HMAC-MD5、HMAC-SHA1、HMAC-SHA256
                • PBKDF2

                  demo例子:

                  var signature = CryptoJS.enc.Utf8.parse(signatureRawData);
                  //var secret_bytes = CryptoJS.enc.Base64.parse(appSecret);
                  var secret_bytes = CryptoJS.enc.Utf8.parse(appSecret);
                  var signatureBytes = CryptoJS.HmacSHA256(signature,secret_bytes)
                  console.log('signatureBytes:', signatureBytes)
                  var signStr = signatureBytes.toString()
                  console.log('signStr:', signStr)
                  var requestSignatureBase64String = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(signStr));
                  console.log('requestSignatureBase64String:', requestSignatureBase64String)
                  

                  总结:

                  HmacSHA256加密,var hash = CryptoJS.HmacSHA256(str, secret);

                  base64编码,var hashInBase64 = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(hash));

                  使用CryptoJS的hmac

                  CryptoJS官方文档:https://cryptojs.gitbook.io/docs/#encoders

                  使用secretkey利用HMAC生成哈希签名。使用SHA256作为哈希算法

                  • CryptoJS.enc.Utf8.parse 把字符串转成UTF8编码

                    您不能简单地将字节发送到JavaScript。您需要将其转换为文本表示形式,以使其具有可比性。python的hmac模块和CryptoJS都支持十六进制编码。

                    CryptoJS:

                    CryptoJS.HmacSHA256(“test”, “secret”).toString(CryptoJS.enc.Hex)

                    python:

                    hmac.new(“secret”, “test”, hashlib.sha256).hexdigest()

                    注意参数顺序的差异。

                    两者都产生

                    0329a06b62cd16b33eb6792be8c60b158d89a2ee3a876fce9a881ebb488c0914

                    5. PostMan 在请求中自动添加Header

                    你可以再postman 的console看到发送的请求的header中添加了你的这里添加的header内容。

                    // 添加新 header
                    pm.request.headers.add({
                        key: 'Accept-Encoding',
                        value: 'gzip'
                    });
                    // 添加或修改已存在 header
                    pm.request.headers.upsert({
                        key: 'Connection',
                        value: 'close'
                    });
                    // 移除 header
                    pm.request.headers.remove('User-Agent')
                    

                    网上demo,这种方式,我们之间就在header中添加了这个 header,不用再到具体的接口header中添加环境变量(如下图),也是很方便。

                    postman之接口参数签名(js接口HMAC-SHA256签名),在这里插入图片描述,第3张

                    postman之接口参数签名(js接口HMAC-SHA256签名),在这里插入图片描述,第4张

                    6. 使用PM对象访问与操作请求参数(pm.request.*)

                    Postman进阶篇(十一)-在脚本中使用pm对象访问接口请求(pm.request.*)

                    参考URL: https://betheme.net/qianduan/44100.html?action=onClick

                    pm.request 对象可以在脚本中对请求数据进行访问。

                    接口请求的URL

                    pm.request.url //接口URL

                    通过URL对象对接口URL进行访问和操作

                    //返回url对象
                    var url = pm.request.url
                    console.log('url:', url)
                    //通过URL对象对接口URL进行访问和操作
                    //返回请求路径:
                    var path = pm.request.url.getPath()
                    console.log('path:', path)
                    var path_with_query = pm.request.url.getPathWithQuery()
                    console.log('path_with_query:', path_with_query)
                    //以字符串格式,返回查询参数
                    var query_string = pm.request.url.getQueryString()
                    console.log('query_string:', query_string)
                    //返回主机和端口,用“:”分隔
                    var remote = pm.request.url.getRemote()
                    console.log('remote:', remote)
                    

                    postman之接口参数签名(js接口HMAC-SHA256签名),在这里插入图片描述,第5张

                    执行结果:

                    postman之接口参数签名(js接口HMAC-SHA256签名),在这里插入图片描述,第6张

                    7. JS字符串拼接/连接

                    在 JavaScript 中,使用字符串连接有 3 种方式。

                    1. 字符串连接运算符“+”
                    2. 字符串的concat()方法
                    var s1 = "abc";
                    var s2 = s1.concat("d" , "e" , "f");  //调用concat()连接字符串
                    console.log(s2);  //返回字符串“abcdef”
                    
                    1. 数组的join()方法

                      join 的好处在于,你可以自定义组合数组元素的方式。你可以通过在其参数中传递分隔符来实现。

                    arrayObject.join(separator);
                    

                    8. JavaScript判断变量是否为空

                    JavaScript判断变量是否为空

                    参考URL: http://aihongxin.com/791.html

                    JavaScript五种原始类型(boolean、number、string、null、undefined)

                    分别为 undefined,null,false,“”,0,

                    JavaScript本身没有判断一个变量是不是空值的函数,因为变量有可能是string,object,number,boolean等类型,类型不同,判断方法也不同。

                    写了一个函数,用以判断JS变量是否空值,如果是undefined、 null、‘’、 NaN、false、0、[]、{} 、空白字符串,都返回true,否则返回false。

                    function isEmpty(v) {
                        switch (typeof v) {
                        case 'undefined':
                            return true;
                        case 'string':
                            if (v.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length == 0) return true;
                            break;
                        case 'boolean':
                            if (!v) return true;
                            break;
                        case 'number':
                            if (0 === v || isNaN(v)) return true;
                            break;
                        case 'object':
                            if (null === v || v.length === 0) return true;
                            for (var i in v) {
                                return false;
                            }
                            return true;
                        }
                        return false;
                    }
                    

                    参考

                    postman自动化接口测试

                    参考URL: https://zhuanlan.zhihu.com/p/158732164

                    Postman调试技巧之接口签名

                    参考URL: https://juejin.cn/post/6844903636649115655

                    postman 配置参数自动签名

                    参考URL: https://blog.csdn.net/qq_28058443/article/details/120704523

                    JSAPI签权

                    参考URL: http://www.javashuo.com/article/p-ubvsvhgx-bc.html

                    postman系列之接口参数签名

                    参考URL: https://blog.csdn.net/henglin/article/details/119621767

网友评论

搜索
最新文章
热门文章
热门标签
 
 孕妇梦见打死蛇还煮的吃了  梦见房屋倒塌自己成功避开  属猴的1992年是什么星座