# 生成签名

# 步骤说明

# 1. 获取时间戳

单位是秒,以字符串的形式保存到变量 timestamp

const timestamp = `${Math.floor(new Date().getTime() / 1000)}`

# 2. 生成随机数

长度固定为 6 位,以字符串的形式保存到变量 nonce

const nonce = `${Math.floor(100000 + Math.random() * 900000)}`

# 3. 拼接参数

将前两步获取的随机数、时间戳以及应用 ID、请求路径、请求方法进行 Key=Value 拼接,并以字典序的方式排序后使用 & 连接。

得到形如 A=sdf&B=dfas&C=21s 的字符串。

# 4. HMAC 运算

算法为 SHA1,秘钥为 AppSecret, 对结果使用 base64 编码。

# 示例代码

示例代码使用 Typescript 编写。

import crypto from 'crypto'
import { APPID, APPSECRET } from './appid'

//#region sign
function genSignature(params: Object, secret: string) {
  let entries = Object.entries(params).sort()
  const querystring = entries
    .map(([key, value]) => {
      return [key, encodeURIComponent(value)]
    })
    .map(([key, value]) => {
      return `${key}=${value}`
    })
    .join('&')

  const hmac = crypto.createHmac('sha1', secret)
  hmac.update(querystring)
  const signature = hmac.digest('base64')
  return signature
}

type HTTPMethod = 'POST' | 'GET' | 'PUT' | 'DELETE'

export default function sign(
  method: HTTPMethod,
  path: string,
  nonce: string,
  timestamp: string
): string {
  const appId = APPID
  const signature = genSignature(
    {
      appId,
      method,
      nonce,
      path,
      timestamp,
    },
    APPSECRET
  )
  return signature
}
//#endregion sign