verify-request-sign.js 2.1 KB
Newer Older
1
const crypto = require('crypto')
2 3 4
const createConfig = require('uni-config-center')
const { verifyHttpInfo } = require('uni-cloud-s2s')

5
const { ERROR } = require('../common/error')
6 7 8
const s2sConfig = createConfig({
  pluginId: 'uni-cloud-s2s'
})
9 10
const needSignFunctions = new Set([
  'externalRegister',
11 12
  'externalLogin',
  'updateUserInfoByExternal'
13 14 15 16
])

module.exports = function () {
  const methodName = this.getMethodName()
17
  const { source } = this.getUniversalClientInfo()
18

19 20 21
  // 指定接口需要鉴权
  if (!needSignFunctions.has(methodName)) return

22 23 24 25 26 27 28
  // 非 HTTP 方式请求拒绝访问
  if (source !== 'http') {
    throw {
      errCode: ERROR.ILLEGAL_REQUEST
    }
  }

29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
  // 支持 uni-cloud-s2s 验证请求
  if (s2sConfig.hasFile('config.json')) {
    try {
      if (!verifyHttpInfo(this.getHttpInfo())) {
        throw {
          errCode: ERROR.ILLEGAL_REQUEST
        }
      }
    } catch (e) {
      if (e.errSubject === 'uni-cloud-s2s') {
        throw {
          errCode: ERROR.ILLEGAL_REQUEST,
          errMsg: e.errMsg
        }
      }
      throw e
    }

    return
  }

50 51 52
  if (!this.config.requestAuthSecret || typeof this.config.requestAuthSecret !== 'string') {
    throw {
      errCode: ERROR.CONFIG_FIELD_REQUIRED,
53
      errMsgValue: {
54 55 56 57 58
        field: 'requestAuthSecret'
      }
    }
  }

59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
  const timeout = 20 * 1000 // 请求超过20秒不能再请求,防止重放攻击
  const { headers, body: _body } = this.getHttpInfo()
  const { 'uni-id-nonce': nonce, 'uni-id-timestamp': timestamp, 'uni-id-signature': signature } = headers
  const body = JSON.parse(_body).params || {}
  const bodyStr = Object.keys(body)
    .sort()
    .filter(item => typeof body[item] !== 'object')
    .map(item => `${item}=${body[item]}`)
    .join('&')

  if (isNaN(Number(timestamp)) || (Number(timestamp) + timeout) < Date.now()) {
    throw {
      errCode: ERROR.ILLEGAL_REQUEST
    }
  }

  const reSignature = crypto.createHmac('sha256', `${this.config.requestAuthSecret + nonce}`).update(`${timestamp}${bodyStr}`).digest('hex')

  if (signature !== reSignature.toUpperCase()) {
    throw {
      errCode: ERROR.ILLEGAL_REQUEST
    }
  }
}