跳转到主要内容

认证与签名

接入 OristaPay Open API 采用 双重认证
  • OAuth2 访问令牌 — 证明调用方身份
  • HMAC 请求签名 — 证明请求未被篡改
每次请求必须同时通过两层校验,任一失败即返回 401 Unauthorized

1. 获取访问令牌

标准 OAuth2 client_credentials 流程。 请求
POST /realms/digitalasset/protocol/openid-connect/token HTTP/1.1
Host: auth.uat.rdezlink.tech
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&client_id={api_key}
&client_secret={api_secret}
响应
{
  "access_token": "eyJhbGciOi...",
  "token_type":   "Bearer",
  "expires_in":   300
}
使用约束
  • access_tokenexpires_in 秒内可复用,建议缓存并在到期前 30 秒主动刷新
  • access_token 必须由与 X-Api-Key 对应的 OAuth 客户端签发
使用 A 商户的 api_key 配合 B 商户的 access_token 调用会被拒绝。

2. 请求签名算法

待签字符串拼接规则
string_to_sign = METHOD + PATH + TIMESTAMP + NONCE + SHA256_HEX(BODY)
签名计算
signature = HEX( HMAC_SHA256( sign_secret, string_to_sign ) )
字段定义
元素定义
METHOD请求方法,全大写,如 POST
PATH接口路径,不含域名与 query,如 /api/v1/wallet/list
TIMESTAMP13 位 UTC 毫秒时间戳字符串,与 X-Timestamp 完全一致
NONCE本次请求唯一随机串,与 X-Nonce 完全一致,建议 32 位 hex
BODY请求体原始字节;无 body 时为空字符串(SHA256_HEX("") = e3b0c442...b855
参考实现
import hashlib
import hmac

def sign(method: str, path: str, ts: str, nonce: str,
         body: str, sign_secret: str) -> str:
    body_hash = hashlib.sha256(body.encode()).hexdigest()
    to_sign   = method + path + ts + nonce + body_hash
    return hmac.new(sign_secret.encode(),
                    to_sign.encode(),
                    hashlib.sha256).hexdigest()

3. 请求头规范

所有业务请求必须同时携带以下请求头:
Header必选说明
AuthorizationBearer {access_token}
X-Api-Key接入方 api_key
X-TimestampUTC 毫秒时间戳,允许 ±5 分钟 偏差
X-Nonce本次请求唯一随机串,5 分钟内同 api_key 下不可复用
X-Signature§2 计算出的签名
Content-Type固定 application/json; charset=utf-8

请求与响应约定

协议规范
项目规范
传输协议HTTPS (TLS 1.2+)
请求方法POST
字符集UTF-8
请求/响应JSON
字段命名camelCase
时间戳毫秒;请求侧字符串/数字皆可,响应侧统一数字

响应信封

所有响应均为单层 JSON { code, message, data? },由下游业务服务返回,网关不再做二次包装。 成功(业务正常) 业务码 code = 1,业务数据在 data 中:
{
  "code":    1,
  "message": "Success",
  "data":    { /* 业务数据;列表接口为数组 */ }
}
业务/下游错误 下游返回业务错误,HTTP 状态码仍为 200,错误细节由业务码 code / message 表达:
{
  "code":    <非 1 整数>,
  "message": "<失败原因>"
}
下游 gRPC 不可达 / 超时等场景,HTTP 状态码仍为 200code 为负整数(与 gRPC StatusCode 取负,如 -14 表示 UNAVAILABLE),message 给出连接错误详情。 网关层错误 路由未命中、网关内部异常、descriptor 缺失等。HTTP 状态码使用对应错误码(如 400 / 404 / 500 / 502),响应体仍为单层 {code, message}
{
  "code": 404,
  "message": "route not found"
}
  • HTTP 状态码反映传输层处理结果:2xx 表示请求成功送达下游并完成转换;非 2xx 表示网关侧错误
  • 业务码 code 反映业务层处理结果:1 表示业务成功,data 承载返回值;其他值为业务错误码,message 给出原因描述
  • 判断成功的正确姿势:HTTP 2xx + 业务 code == 1,两者皆满足才表示业务调用成功
  • 认证类错误Authorization / X-Signature / X-Timestamp / X-Nonce 任一校验失败统一返回 HTTP 401,响应体为 {"code":401,"message":"Unauthorized"}

错误处理

HTTP 状态码与业务码

响应体统一为单层 {code, message, data?}。HTTP 状态码反映网关/传输层结果,业务码 code 反映业务处理结果。
HTTP Status含义响应体建议
200 + code == 1业务成功{code:1, message, data}data 取业务字段
200 + code != 1下游业务错误{code, message}message 处理业务错误
200 + code < 0请求送达后 gRPC 异常{code, message}code 为 gRPC 状态码取负)检查下游可用性,必要时重试
400请求体或参数非法{code, message}修正后重试
401认证失败(OAuth 或签名){code:401, message}按下方排查清单逐项检查
404接口不存在{code, message}核对路径
429触发限流{code, message, ...}退避后重试
5xx网关或下游服务异常{code, message}指数退避后重试

认证失败排查清单

所有认证类错误统一返回:
{ "code": 401, "message": "Unauthorized" }
请按以下顺序排查:
  1. Token 是否有效 — 是否过期?是否由当前 api_key 签发?
  2. 签名是否匹配METHOD / PATH / BODY 是否与实际发送一致?
  3. 时间戳是否在窗口内 — 本机时钟是否与 NTP 同步?
  4. Nonce 是否唯一 — 5 分钟内同一 api_key 下不得复用

限流策略

维度api_key 独立计量
默认配额600 次 / 分钟
超限响应HTTP 429
超限响应示例
{
  "code":      429,
  "message":   "rate limit exceeded",
  "limit":     600,
  "window_ms": 60000
}
需要更高配额请联系商务,调整后次分钟生效。

安全建议

主题最佳实践
密钥管理api_secretsign_secret 仅在服务端使用,严禁下发到前端或移动端
凭证轮换定期轮换;发现泄露立即联系商务重置
传输安全强制 HTTPS,拒绝任何未启用 TLS 1.2+ 的客户端
时钟同步使用 NTP 保持 ±1 分钟内的精度,避免时钟漂移引发误判
日志脱敏应用日志中不得保存完整 api_secret / sign_secret / access_token