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

.NET Core HttpClient调用WooCommerce API遇OAuth 401无效签名问题

WooCommerce OAuth 1.0签名无效(401未授权)排查与修复

以下是导致签名验证失败的核心问题及修复方案:

1. 请求头语法错误

代码中oauth_signature_method=\"HMAC-SHA1'使用单引号闭合,应为双引号,导致服务器无法正确解析参数。

2. 签名基字符串构建逻辑错误

OAuth 1.0要求:

  • 所有OAuth参数需按字典序排序
  • 拼接成key=value&key=value格式后整体URL转义
    而非每个参数单独转义后拼接,否则会导致参数间的&处理异常,破坏签名的正确性。

3. 请求URL与签名基字符串URL不一致

签名基字符串中的URL是https://loomina.ir/wp-json/wc/v3/products(无末尾斜杠),但实际请求URL带末尾斜杠,URL规范化必须完全一致,否则签名验证不通过。

4. Authorization头参数分隔符缺失空格

OAuth头参数需用, (逗号加空格)分隔,而非直接逗号,部分服务器对格式要求严格,会导致参数解析失败。


修正后的代码

生成OAuth签名头方法

public static string GetoAuthToken(string conKey, string conSecret, string requestUrl)
{
    // 生成标准Unix时间戳(秒级)
    long timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
    string timestampStr = timestamp.ToString();

    // 生成唯一Nonce(GUID更可靠)
    string nonce = Guid.NewGuid().ToString("N");

    // 按字典序存储OAuth参数
    var oauthParams = new SortedDictionary<string, string>
    {
        { "oauth_consumer_key", conKey },
        { "oauth_nonce", nonce },
        { "oauth_signature_method", "HMAC-SHA1" },
        { "oauth_timestamp", timestampStr },
        { "oauth_version", "1.0" }
    };

    // 拼接参数为key=value&key=value格式
    string paramString = string.Join("&", oauthParams.Select(kv => $"{Uri.EscapeDataString(kv.Key)}={Uri.EscapeDataString(kv.Value)}"));

    // 构建签名基字符串
    string signatureBaseString = $"GET&{Uri.EscapeDataString(requestUrl)}&{Uri.EscapeDataString(paramString)}";

    // 生成HMAC-SHA1签名
    string signature = GetSha1Hash($"{conSecret}&", signatureBaseString);

    // 构建符合格式的Authorization头
    string authHeader = string.Join(", ", oauthParams.Select(kv => $"{kv.Key}=\"{Uri.EscapeDataString(kv.Value)}\"")
        .Append($"oauth_signature=\"{Uri.EscapeDataString(signature)}\""));

    return authHeader;
}

SHA1哈希生成方法(优化编码兼容性)

public static string GetSha1Hash(string key, string baseSignatureString)
{
    var encoding = System.Text.Encoding.UTF8; // 兼容非ASCII字符

    byte[] keyBytes = encoding.GetBytes(key);
    byte[] messageBytes = encoding.GetBytes(baseSignatureString);

    using (HMACSHA1 hmacSha1 = new HMACSHA1(keyBytes))
    {
        byte[] hashedBytes = hmacSha1.ComputeHash(messageBytes);
        return Convert.ToBase64String(hashedBytes);
    }
}

请求代码修正

// 确保URL与签名基字符串完全一致(去除末尾斜杠)
string requestUrl = $"{websites.Url.TrimEnd('/')}/wp-json/wc/v3/products";
var oAuthSignature = Utility.GetoAuthToken(websites.CustomerKey, websites.CustomerSecret, requestUrl);
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("OAuth", oAuthSignature);
var response = await _client.GetAsync(requestUrl);
var result = await response.Content.ReadAsStringAsync();

额外注意点

  • Nonce需保证每次请求唯一,使用GUID比重复timestamp更可靠
  • 签名生成后需进行URL转义,避免特殊字符破坏头格式
  • 参数排序必须严格按字典序,这是OAuth 1.0签名验证的强制要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 23:00:53