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

React Native对接WordPress OAuth1签名验证失败求助

让我们一步步排查你的问题,先解决之前的「Consumer Key is invalid」错误,再搞定核心的「OAuth signature does not match」问题:

首先解决「Consumer Key is invalid」的问题

你之前的Authorization头格式存在两个不符合OAuth 1.0规范的问题:

  • OAuth参数之间需要用逗号加空格分隔,而非单纯的逗号(服务器解析时可能会把参数连在一起,导致consumer key识别错误)
  • OAuth参数的值需要用双引号包裹(规范要求的格式)

修正后的Authorization头开头示例:

"Authorization": "OAuth oauth_consumer_key=\"ieQCM48wXWuW\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"123456789\", oauth_nonce=\"FFeySWNH1Am\", oauth_version=\"1.0\", oauth_signature=\"你的正确签名\""

核心问题:「OAuth signature does not match」的原因及解决方法

签名不匹配几乎都是因为基字符串、签名密钥、签名编码格式三者之一不符合规范,我们逐个拆解修复:

1. 确保基字符串与请求参数完全一致

你的代码里存在一个致命的不一致:

  • Authorization头里的oauth_nonce是FFeySWNH1Am
  • 但生成签名用的基字符串里oauth_nonce是nonce

这直接导致签名与实际请求参数不匹配,服务器验证必然失败。生成基字符串时,必须保证所有OAuth参数(包括nonce、timestamp)与请求头里的内容完全一致。

另外,基字符串的构造必须严格遵循以下规则:

  • 开头是大写的HTTP方法(比如POST)
  • 第二部分是URL编码后的完整请求URL(必须和fetch的URL完全一致,包括协议、域名、路径)
  • 第三部分是URL编码后的所有OAuth参数串:
    • 先把所有OAuth参数(除了oauth_signature本身)按字典序排序
    • 每个参数的键和值分别做URL编码(遵循RFC 3986,用%20代替空格,不要用+)
    • 用&连接所有编码后的键值对
  • 三部分用&连接,不要用HTML转义的&,必须用原始的&

针对你的请求,正确的基字符串应该是:

POST&http%3A%2F%2Fauth-test-site.azurewebsites.net%2Foauth1%2Frequest&oauth_consumer_key%3DieQCM48wXWuW&oauth_nonce%3DFFeySWNH1Am&oauth_signature_method%3DHMAC-SHA1&oauth_timestamp%3D123456789&oauth_version%3D1.0

2. 使用正确的签名密钥

HMAC-SHA1的签名密钥规则是:consumer_secret&token_secret

  • 在请求令牌(request token)阶段,你还未获取到access token,所以token_secret是空字符串,因此密钥必须是你的consumer_secret&(注意末尾的&不能省略)

你的consumer secret是9Yf0HG8RWrk0a4IKxwnkK2LUvd15NNF0b98jZwpOmQhoO7vv,所以签名密钥为:

9Yf0HG8RWrk0a4IKxwnkK2LUvd15NNF0b98jZwpOmQhoO7vv&

3. 用正确格式生成签名

OAuth 1.0要求签名是HMAC-SHA1哈希的Base64编码结果,而非十六进制字符串!你之前用在线工具生成的是十六进制值(5c6f358b1086cf2387e46a6c00e412fcfc2a4743),这不符合规范,必须转成Base64。

你可以用JavaScript直接生成正确签名,避免依赖在线工具:

Node.js环境:

const crypto = require('crypto');

const baseString = 'POST&http%3A%2F%2Fauth-test-site.azurewebsites.net%2Foauth1%2Frequest&oauth_consumer_key%3DieQCM48wXWuW&oauth_nonce%3DFFeySWNH1Am&oauth_signature_method%3DHMAC-SHA1&oauth_timestamp%3D123456789&oauth_version%3D1.0';
const consumerSecret = '9Yf0HG8RWrk0a4IKxwnkK2LUvd15NNF0b98jZwpOmQhoO7vv';
const signingKey = `${consumerSecret}&`;

const signature = crypto.createHmac('sha1', signingKey)
  .update(baseString)
  .digest('base64');

console.log(signature); // 这就是你需要的oauth_signature值

浏览器环境(Web Crypto API):

async function generateSignature(baseString, signingKey) {
  const encoder = new TextEncoder();
  const keyData = encoder.encode(signingKey);
  const baseStringData = encoder.encode(baseString);
  
  const key = await crypto.subtle.importKey(
    'raw', keyData, { name: 'HMAC', hash: 'SHA-1' }, false, ['sign']
  );
  
  const signatureBuffer = await crypto.subtle.sign('HMAC', key, baseStringData);
  return btoa(String.fromCharCode(...new Uint8Array(signatureBuffer)));
}

// 调用示例
generateSignature(
  'POST&http%3A%2F%2Fauth-test-site.azurewebsites.net%2Foauth1%2Frequest&oauth_consumer_key%3DieQCM48wXWuW&oauth_nonce%3DFFeySWNH1Am&oauth_signature_method%3DHMAC-SHA1&oauth_timestamp%3D123456789&oauth_version%3D1.0',
  '9Yf0HG8RWrk0a4IKxwnkK2LUvd15NNF0b98jZwpOmQhoO7vv&'
).then(signature => {
  console.log(signature);
});

4. 修正后的完整请求代码

整合所有修正点后,你的fetch请求应该是这样的:

const url = 'http://auth-test-site.azurewebsites.net/oauth1/request';
const oauthNonce = 'FFeySWNH1Am';
const oauthTimestamp = '123456789';
const consumerKey = 'ieQCM48wXWuW';
const consumerSecret = '9Yf0HG8RWrk0a4IKxwnkK2LUvd15NNF0b98jZwpOmQhoO7vv';

// 构造基字符串
const encodedUrl = encodeURIComponent(url);
const params = [
  `oauth_consumer_key=${encodeURIComponent(consumerKey)}`,
  `oauth_nonce=${encodeURIComponent(oauthNonce)}`,
  `oauth_signature_method=${encodeURIComponent('HMAC-SHA1')}`,
  `oauth_timestamp=${encodeURIComponent(oauthTimestamp)}`,
  `oauth_version=${encodeURIComponent('1.0')}`
].sort().join('&');
const encodedParams = encodeURIComponent(params);
const baseString = `POST&${encodedUrl}&${encodedParams}`;

// 生成签名(这里用Node.js示例,浏览器环境替换为Web Crypto函数)
const crypto = require('crypto');
const signingKey = `${consumerSecret}&`;
const oauthSignature = crypto.createHmac('sha1', signingKey)
  .update(baseString)
  .digest('base64');

fetch(url, {
  method: "POST",
  headers: {
    "Accept": "application/json",
    "Content-Type": "application/x-www-form-urlencoded",
    "Authorization": `OAuth oauth_consumer_key="${consumerKey}", oauth_signature_method="HMAC-SHA1", oauth_timestamp="${oauthTimestamp}", oauth_nonce="${oauthNonce}", oauth_version="1.0", oauth_signature="${oauthSignature}"`
  },
  credentials: "same-origin"
})
.then(response => response.text())
.then(text => console.log(text))
.catch(error => console.error(error.message));

额外注意事项

  • 生产环境不要硬编码nonce和timestamp:nonce应该是每次请求唯一的随机字符串,timestamp应该是当前的Unix时间戳(秒数),否则服务器可能会拒绝重复请求。
  • 确保所有URL编码严格遵循RFC 3986:比如!、*、()这些字符也要编码,不要只编码空格和常见特殊符号。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:24:30