跳到主要内容

HTTP 定制化接口流程

HTTP 流程开发

  1. 接口定义

    接口定义

    接口英文名: 不能重复,否则无法匹配指定接口

    文档:定义文档,方便生成 swagger,否则网关返回的 swagger 中将不包含该接口定义信息

    其余说明参考该节点帮助手册

  2. 开发流程逻辑

    在「接口定义」节点与「接口响应」节点之间开发流程

  3. 响应接口

    接口响应

HTTP 接口调试

  1. 通过 OcsController 接口文档面板调试

    接口文档面板调试

  2. 通过网关调用-Token 认证机制

  • 请求地址
  • 请求说明
    • 在 herders 中添加 Authorization 请求头,内容为登录后生成的 Token
    • 适用于客户端发起请求
  1. 通过网关调用-AK/SK 认证机制

ApiFox AK/SK 调试

其中 AccessKeySecret、AccessKeyId 值需使用者自行设置在 ApiFox 环境变量中:

ApiFox配置1

新建公共脚本:

ApiFox配置2

脚本详细:

'use strict'
const cryptoJS = require('crypto-js');


/**
* 签名生成参照 https://apifox.com/apidoc/shared-428aaa18-d8e4-426d-8b01-96b0473b9ca2/doc-1359849
* @param signedParams 签名参数,body 参数不参与签名
* @param httpMethod http 请求方法
* @param secret 签名密钥
* @return {string || null}
*/
function getSignature(signedParams, httpMethod, secret) {
if (!signedParams || Object.keys(signedParams) < 1 || !secret || !httpMethod) {
return null
}
const normalized = normalize(signedParams)
const canonicalized = canonicalize(normalized)
const stringToSign = `${httpMethod}&${encode('/')}&${encode(canonicalized)}`
const key = secret + '&'

let signatureStr = cryptoJS.HmacSHA1(stringToSign, key).toString(cryptoJS.enc.Base64)

if (httpMethod !== 'POST') {
signatureStr = encodeURIComponent(signatureStr)
}
return signatureStr
}

function normalize(params) {
const list = []
const flated = {}
flatMap(flated, params)
const keys = Object.keys(flated).sort()
for (let i = 0; i < keys.length; i++) {
const key = keys[i]
const value = flated[key]
list.push([encode(key), encode(value)])
}
return list
}

function flatMap(target, params, prefix = '') {
if (prefix) {
prefix = prefix + '.'
}
let keys = Object.keys(params)
for (let i = 0; i < keys.length; i++) {
let key = keys[i]
let value = params[key]
key = prefix + key
if (typeof value === 'undefined' || value == null) {
continue
}

if (Array.isArray(value)) {
replaceRepeatList(target, value, key)
} else if (value instanceof Object) {
flatMap(target, value, key)
} else {
target[key] = value.toString()
}
}
return target
}

function replaceRepeatList(target, repeat, prefix) {
if (prefix) {
prefix = prefix + '.'
}
for (let i = 0; i < repeat.length; i++) {
const item = repeat[i]
const key = prefix + (i + 1)
if (typeof item === 'undefined' || item == null) {
continue
}
if (Array.isArray(item)) {
replaceRepeatList(target, item, key)
} else if (item instanceof Object) {
flatMap(target, item, key)
} else {
target[key] = item.toString()
}
}
}

function encode(str) {
const result = encodeURIComponent(str)

return result
.replace(/!/g, '%21')
.replace(/'/g, '%27')
.replace(/\(/g, '%28')
.replace(/\)/g, '%29')
.replace(/\*/g, '%2A')
}

function canonicalize(normalized) {
const fields = []
for (let i = 0; i < normalized.length; i++) {
const [key, value] = normalized[i]
fields.push(key + '=' + value)
}
return fields.join('&')
}


const headers = {
Timestamp: new Date().toISOString().slice(0, 19) + 'Z',
AccessKeyId: pm.environment.get('AccessKeyId'),
SignatureNonce: Date.now().toString()
}

const queryParams = pm.request.url.query
const newQueryParams = {}
queryParams.each(item => {
if (!item.disabled) {
newQueryParams[item.key] = item.value
}
})

pm.request.headers.add({ key: 'Timestamp', value: headers.Timestamp })
pm.request.headers.add({ key: 'Signature', value: getSignature({...headers, ...newQueryParams}, pm.request.method.toUpperCase(), pm.environment.get('AccessKeySecret')) })
pm.request.headers.add({ key: 'AccessKeyId', value: pm.environment.get('AccessKeyId') })
pm.request.headers.add({ key: 'SignatureNonce', value: headers.SignatureNonce })