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

Ruby函数生成的HMAC-SHA256 $sb_token无效,IRB手动执行却正常?

问题排查与解决方案

核心排查方向

导致函数生成的令牌无效、手动执行却有效的常见原因集中在字符串换行符差异、全局变量值不一致以及签名计算细节偏差这几点,逐一排查如下:

  1. 修复换行符的硬编码问题
    你代码中构建signature时用了硬换行:

    signature = encoded + '
    ' + ttl
    

    这种写法会让字符串中包含当前系统的换行符(Windows是\r\n,Unix是\n),而手动在IRB中执行时你大概率是写的encoded + "\n" + ttl,统一用\n换行符才符合Service Bus签名要求。修改为:

    signature = "#{encoded}\n#{ttl}"
    
  2. 验证全局变量的一致性
    函数依赖$resourceUri、$sasKeyName、$sasKey三个全局变量,务必确认函数执行时这些变量的值和你手动在IRB中测试时完全一致。可以在函数开头添加打印语句:

    puts "resourceUri: #{$resourceUri}"
    puts "sasKeyName: #{$sasKeyName}"
    puts "sasKey: #{$sasKey}"
    

    对比手动执行时的输出,避免函数调用前全局变量被意外修改。

  3. 逐字符对比令牌差异
    分别打印函数生成的$sb_token和手动生成的令牌,对比每一部分:

    • sr部分的URL编码是否一致
    • sig部分的Base64编码结果是否相同
    • se的时间戳是否在有效期内(虽然40103是签名错误,但也要排除时间差导致的问题)
      重点看sig,只要这里有差异,签名就会验证失败。
  4. 替换全局变量为函数参数(推荐)
    全局变量容易引发不可预见的副作用,把参数传入函数能彻底避免这类问题:

    def get_service_bus_token(resource_uri, sas_key_name, sas_key)
      encoded = ERB::Util.url_encode(resource_uri)
      now = Time.now.to_i
      ttl = (now + 60).to_s
      signature = "#{encoded}\n#{ttl}"
      digest = OpenSSL::Digest.new('sha256')
      hmac = OpenSSL::HMAC.digest(digest, sas_key, signature)
      hash = Base64.strict_encode64(hmac)
      "SharedAccessSignature sr=#{encoded}&sig=#{ERB::Util.url_encode(hash)}&se=#{ttl}&skn=#{sas_key_name}"
    end
    

    调用时直接传入参数:

    $sb_token = get_service_bus_token($resourceUri, $sasKeyName, $sasKey)
    

验证方法

修改后,先在IRB中调用函数生成令牌,和手动步骤生成的令牌对比,确认完全一致后再发起HTTP请求。

内容的提问来源于stack exchange,提问作者J. Naylor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 08:57:51