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

使用PHP生成OAuth 1.0签名失败,API返回401无效签名求助

解决OAuth 1.0调用返回401无效签名的问题

问题根源分析

你的代码存在两个核心问题,直接导致了无效签名的401错误:

  • Authorization头语法错误:oauth_signature字段的引号闭合逻辑错误,原代码中多写了一个闭合引号,导致API无法正确解析签名内容。
  • Nonce生成不符合规范:OAuth 1.0要求nonce是每个请求唯一的随机字符串,同一时间戳下不能重复。你当前的实现基于截短的时间戳生成,同一分钟内所有请求的nonce完全相同,违反了唯一性要求。

修正后的代码

const consumer_key = "20CECD28B41A458E9E328BB45C26EACB";
const consumer_secret = "F485B390C5854A69A8DA17554E689D03";
const token = "5F3C117598A14BE8B7136659AB2251C0";
const token_secret = "647E14C4F7EF4DA5AA119D5C60E95114";

// 生成符合OAuth规范的唯一随机nonce
function generateNonce() {
    return bin2hex(random_bytes(16));
}

function generateSignature($request, $timestamp, $nonce){
    // 按字典序排列OAuth参数(必须严格排序)
    $params = [
        'oauth_consumer_key' => consumer_key,
        'oauth_nonce' => $nonce,
        'oauth_signature_method' => "HMAC-SHA1",
        'oauth_timestamp' => $timestamp,
        'oauth_token' => token,
        'oauth_version' => "1.0"
    ];
    
    // 构建编码后的参数字符串
    $paramString = '';
    foreach ($params as $key => $value) {
        $paramString .= rawurlencode($key) . '=' . rawurlencode($value) . '&';
    }
    $paramString = rtrim($paramString, '&');
    
    // 构建签名基字符串
    $base = $request['method'] . "&" . rawurlencode($request['url']) . "&" . rawurlencode($paramString);

    $key = rawurlencode(consumer_secret) . '&' . rawurlencode(token_secret);
    $signature = base64_encode(hash_hmac('SHA1', $base, $key, true));
    return $signature;
}

$ch = curl_init();

$request = [
    'url' => 'https://someniceapi.com',
    'method' => 'GET'
];

curl_setopt($ch, CURLOPT_URL, $request['url']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request['method']);

$timestamp = time();
$nonce = generateNonce();
$signature = generateSignature($request, $timestamp, $nonce);

// 修正Authorization头的引号错误
$headers = [
    'Authorization: OAuth oauth_consumer_key="'.consumer_key.'",oauth_token="'.token.'",oauth_signature_method="HMAC-SHA1",oauth_signature="'.$signature.'",oauth_timestamp="'.$timestamp.'",oauth_nonce="'.$nonce.'",oauth_version="1.0"'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);

// 可选:添加curl错误排查
if(curl_errno($ch)){
    echo 'Curl错误: ' . curl_error($ch);
}
curl_close($ch);

关键修正说明

  1. Nonce生成:改用random_bytes(16)生成随机字节并转十六进制,确保每个请求的nonce唯一,完全符合OAuth 1.0规范。
  2. Authorization头修复:修正了oauth_signature字段的引号闭合逻辑,保证参数格式被API正确解析。
  3. 参数字符串构建:改用循环拼接参数,更清晰地遵循“键值对分别编码后用&连接”的规则,避免手动拼接的疏漏。

额外验证提示:确保本地服务器时间与API服务器时间偏差在5分钟内,OAuth通常允许这个时间误差,超出范围会导致timestamp无效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 07:43:19