You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Faraday实现自定义HMAC授权:Ruby API封装认证失败问题排查

问题背景

我正在开发对接第三方API的Ruby封装库,该API使用的特殊授权逻辑暂无Faraday内置支持,需要自行实现授权头生成逻辑。官方文档给出的认证规则如下:

你的API凭证由公开客户端标识符(UUIDv4格式)和Base64编码的32字节私钥组成,组织级请求采用类Amazon风格的HMAC认证

官方给出的授权头构造规范如下:

Content-MD5: base64(md5(body)), RFC 1864 (binary md5)
Content-Type: 'application/json'
Date: 'Mon, 07 Dec 2015 22:57:52 +0200' (RFC 2822)
Authorization: 'Success ' + client_identifier + ':' +
    base64(
      sha512_hmac( // returned as binary
        join(
          '\n', // unix newline, not the 2 character string
          [
            http_verb,    // 'POST' / 'GET' / etc.
            Content-MD5,  // Same as header above. Include even for empty string body.
            Content-Type, // Same as header above. Can be empty.
            Date,         // Same as header above.
            http_path     // '/api/v1/document/?foo=bar'
          ]
        ),
        key // in binary, remember to decode base64
      )
    )

我目前编写的实现代码如下:

def create_authorization_header(path, payload)
    date = Date.today.rfc2822            
    md5_file = Digest::MD5.hexdigest(payload)
    content_md5 = Base64.strict_encode64(md5_file)
    digest = OpenSSL::Digest.new('sha512')                
    autorization_header = "GET " + content_md5 + " application/json " + date + path
    autorization_header_enc =  'Success '+ identifier + ':' + Base64.strict_encode64(OpenSSL::HMAC.digest(digest, api_key, autorization_header))
    connection.headers['Authorization'] = autorization_header_enc
    connection.headers['Content-MD5'] = content_md5
    connection.headers['Content-type'] = "application/json"     
    connection.headers['Date'] = date       
end

这段代码运行后始终无法通过API认证,找不到问题点,以下是可能的错误原因:


错误原因排查
  • Content-MD5计算不符合规范:RFC 1864要求对MD5的二进制结果做Base64编码,当前代码使用Digest::MD5.hexdigest得到的是十六进制字符串,再编码后结果完全不符合要求。正确写法为content_md5 = Base64.strict_encode64(Digest::MD5.digest(payload))。
  • 签名字符串拼接规则错误:规范要求各个字段用Unix换行符\n拼接,当前代码用空格拼接,直接不满足签名规则,需要把拼接的分隔符替换为\n。
  • API密钥未做Base64解码:官方明确说明私钥是Base64编码的32字节内容,计算HMAC时需要先对api_key做Base64解码得到二进制密钥,直接用原始Base64字符串作为密钥计算的结果肯定不匹配。
  • 日期生成不符合要求:当前使用Date.today生成的只有日期没有时分秒和时区信息,不符合RFC 2822要求的完整时间戳格式,应该替换为Time.now.rfc2822。
  • HTTP动词硬编码:当前代码把请求方法硬写为GET,如果实际请求是POST、PUT等其他方法,签名会直接不匹配,建议把请求方法作为参数传入动态拼接。
  • 路径参数不完整:需要确认传入的path包含完整的查询参数,类似示例中?foo=bar的部分不能遗漏,否则也会导致签名校验失败。
  • 拼写问题(可选):如果代码运行报错,可检查是否是变量名autorization_header拼写错误(正确应为authorization_header,少了字母h),如果运行无异常可忽略该问题。

内容的提问来源于stack exchange,提问作者Daniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 08:45:04