接口签名和postman预处理生成签名

nestjs后端代码

controller

 @Get('md5hmacSHA1b64')
  postMd5hmacSHA1b64(@Req() request: Request, @Query() query) {
    // 获取GET请求参数
    const queryParamsMap = new Map(Object.entries(query));
    return this.handleMd5hmacSHA1b64(queryParamsMap, request);
  }

  @Post('md5hmacSHA1b64')
  @UseInterceptors(NoFilesInterceptor())
  getMd5hmacSHA1b64(@Req() request: Request, @Body() formData) {
    //@Body() formData 支持 x-www-form-urlencoded 和 application/json 类型的请求, 但是不支持普通表单 form-data
    //form-data支持文件上传, x-www-form-urlencoded不支持文件上传
    //使用 @UseInterceptors(NoFilesInterceptor()) 让@Body()支持form-data键值对形式的非文件上传场景
    console.log('formData:', formData);
    //提取formData的键值对
    const query2 = new Map(Object.entries(formData));
    console.log('query2:', query2);
    return this.handleMd5hmacSHA1b64(query2, request);
  }

  private handleMd5hmacSHA1b64(
    queryParamsMap: Map<string, any>,
    request: Request,
  ) {
    //获取header列表
    //const queryHeadersMap = new Map(Object.entries(request.headers));
    //queryHeadersMap 只取出指定header accessKeyId nonce timestamp
    const queryHeadersMap2 = new Map(
      Object.entries(request.headers).filter(
        (item) =>
          item[0] === 'accesskeyid' ||
          item[0] === 'nonce' ||
          item[0] === 'timestamp' ||
          item[0] === 'sign',
      ),
    );
    //queryHeadersMap2 的 key  accesskeyid 替换为 accessKeyId
    queryHeadersMap2.forEach((value, key) => {
      if (key === 'accesskeyid') {
        queryHeadersMap2.set('accessKeyId', value);
        queryHeadersMap2.delete('accesskeyid');
      }
    });
    //将上面两个map合并
    const allMap = new Map([...queryParamsMap, ...queryHeadersMap2]);
    return this.epgService.md5hmacSHA1b64(allMap);
  }

private handleMd5hmacSHA1b64(
    queryParamsMap: Map<string, any>,
    request: Request,
  ) {
    //获取header列表
    //const queryHeadersMap = new Map(Object.entries(request.headers));
    //queryHeadersMap 只取出指定header accessKeyId nonce timestamp
    const queryHeadersMap2 = new Map(
      Object.entries(request.headers).filter(
        (item) =>
          item[0] === 'accesskeyid' ||
          item[0] === 'nonce' ||
          item[0] === 'timestamp' ||
          item[0] === 'sign',
      ),
    );
    //queryHeadersMap2 的 key  accesskeyid 替换为 accessKeyId
    queryHeadersMap2.forEach((value, key) => {
      if (key === 'accesskeyid') {
        queryHeadersMap2.set('accessKeyId', value);
        queryHeadersMap2.delete('accesskeyid');
      }
    });
    //将上面两个map合并
    const allMap = new Map([...queryParamsMap, ...queryHeadersMap2]);
    return this.epgService.md5hmacSHA1b64(allMap);
  }

service代码

md5hmacSHA1b64(allMap: Map<string, any>) {
    const accessKeyId =process.env.ACCESS_KEY_ID;
    const accessKeySecret = process.env.ACCESS_KEY_SECRET;

    console.log(allMap);
    //遍历allMap列表,拷贝到headerMap
    const sign = allMap.get('sign');
    console.log("sign", sign)
    const headerMap = {};
    for (const key of allMap.keys()) {
      // 去掉名为sign的key
      if (key !== 'sign') {
        headerMap[key] = allMap.get(key);
      }
    }
    console.log('headerMap=', headerMap)
    //accessKeyId 替换为约定的accessKeyId
    headerMap['accessKeyId'] = accessKeyId;

    //对headerMap按字母排序
    const sortHeaderMap = {};
    Object.keys(headerMap)
        .sort()
        .forEach((key) => {
          sortHeaderMap[key] = headerMap[key];
        });
    console.log('sortHeaderMap=', sortHeaderMap);

    //对排序后的header拼接字符串 形如 key1=value1&key2=value2&key3=value3的形式,最后一项没有&
    let str = '';
    for (const key in sortHeaderMap) {
      str += key + '=' + sortHeaderMap[key] + '&';
    }
    str = str.substring(0, str.length - 1);

    //base64
    const base64 = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str));
    //hmacsha1
    const hmacsha1 = CryptoJS.HmacSHA1(base64, accessKeySecret);
    //md5
    const md5 = CryptoJS.MD5(hmacsha1).toString();
    //判断sign==md5 若相等 返回check 字段为ok
    return {
      str,
      md5hmacSHA1b64: md5,
      check: sign === md5?'ok':'no',
    };
  }

postman接口

header定义

pre-Request预处理脚本

// 辅助函数:补零
function padZero(num) {
    return num.toString().padStart(2, '0');
}
// 生成16位随机数,用于nonce
function generateRandom16bit() {
    return Math.random().toString(16).substring(2, 18);
}
//验证请求GET POST ok
let accessKeyId = "UC1"; //签名Key
let accessKeySecret = "UC2"; //签名secret
//let accessKeyId = pm.request.headers.get("accessKeyId");

let param = {};
console.log("param:",param)


// 获取当前时间戳
const now = new Date();
// 时间戳 格式化为指定样式  yyyyMMddHHmmss
const formattedTimestamp = 
    now.getFullYear().toString() + // 年份
    padZero(now.getMonth() + 1) + // 月份,注意月份是从0开始的,所以加1
    padZero(now.getDate()) +
    padZero(now.getHours()) +
    padZero(now.getMinutes()) +
    padZero(now.getSeconds());

//16位随机数
let nonce = generateRandom16bit()

//头部参数
param['accessKeyId']=accessKeyId
param['nonce']=nonce
param['timestamp']=formattedTimestamp

//Get 参数
let queryParam = pm.request.url.query.members;
console.log("queryParam:",queryParam)
for (let i in queryParam){
    param[queryParam[i].key] = queryParam[i].value;
}
//POST参数
let postParam = request.data;
console.log("postParam:",postParam)
if(typeof(postParam) == "string"){
    try{
        let dataJson = JSON.parse(postParam);
        // 将解析后的数据合并到param对象中
        Object.assign(param, dataJson);
    }catch(err){
        console.log(err)
    }
}else{
    Object.assign(param, postParam);
}

console.log("allParam:",param)
//Post
//取key
var keys = [];
for (let k in param){
    if (k == 'sign'){
        continue;
    }
    keys.push(k); 
}
//排序
keys.sort();

//取value
var kv = [];
for (let k of keys){
    kv.push(k + '=' + param[k]) 
    
}

//拼接
var str = kv.join('&');

console.log("str=",str)
//签名计算算法md5(hmacsha1(base64(str)))
const base64 = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str));
const hmacsha1 = CryptoJS.HmacSHA1(base64, accessKeySecret);
const md5 = CryptoJS.MD5(hmacsha1).toString();

//设置环境变量
postman.setEnvironmentVariable("nonce", nonce);
postman.setEnvironmentVariable("timestamp", formattedTimestamp);
postman.setEnvironmentVariable("sign", md5);

相关推荐

  1. go-zero接口签名

    2024-06-07 01:54:02       47 阅读
  2. http请求签名生成算法

    2024-06-07 01:54:02       41 阅读
  3. Mac 生成Android签名证书 .keystore文件

    2024-06-07 01:54:02       48 阅读
  4. open ssl 生成签名证书

    2024-06-07 01:54:02       35 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-07 01:54:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-07 01:54:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-07 01:54:02       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-07 01:54:02       20 阅读

热门阅读

  1. Meta Llama 3 大型语言模型的超参数

    2024-06-07 01:54:02       10 阅读
  2. 源代码先转字节码,再转机器码的过程

    2024-06-07 01:54:02       10 阅读
  3. 【redis】set和zset常用命令

    2024-06-07 01:54:02       12 阅读
  4. Go 语言的控制结构:条件与循环

    2024-06-07 01:54:02       11 阅读
  5. python opencv运行报错

    2024-06-07 01:54:02       10 阅读
  6. python pytorch之torch.flip 按轴翻转/倒叙排列 方法

    2024-06-07 01:54:02       10 阅读
  7. mysql like 查询优化

    2024-06-07 01:54:02       8 阅读
  8. c++ 函数作为参数

    2024-06-07 01:54:02       13 阅读