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

Node.js中通过OAuth1调用Twitter API返回401未授权问题

解决Node.js Lambda调用Twitter API v2时的401未授权错误

你遇到的401错误主要由三个核心问题导致:请求体格式不正确、缺少OAuth1必需的oauth_body_hash参数,以及错误的成功状态码判断。以下是具体的修正方案:

核心问题解析

  • 请求体格式错误:直接传递JavaScript对象作为fetch的body参数,会被默认处理为FormData,但Twitter API v2要求JSON格式的请求体。
  • 缺失OAuth Body Hash:发送JSON格式的POST请求时,Twitter要求OAuth1签名必须包含oauth_body_hash(请求体的SHA1哈希值,base64编码),用于验证请求完整性,缺少该参数会导致签名无效。
  • 错误的状态码判断:Twitter创建推文成功返回的是201 Created,而非200 OK,原代码会误判成功请求为错误。

修正后的完整代码

const fetch = require('node-fetch');
const OAuth = require('oauth-1.0a');
const crypto = require('crypto');

const oauth = OAuth({
  consumer: {
      key: '你的consumer key',
      secret: '你的consumer secret',
  },
  signature_method: 'HMAC-SHA1',
  hash_function(base_string, key) {
      return crypto
          .createHmac('sha1', key)
          .update(base_string)
          .digest('base64')
  },
});

// 准备推文内容并转为JSON字符串
const tweetPayload = { text: 'Hello World!' };
const requestBody = JSON.stringify(tweetPayload);

// 计算OAuth Body Hash:请求体的SHA1哈希值(base64编码)
const bodyHash = crypto.createHash('sha1').update(requestBody).digest('base64');

const requestData = {
  url: 'https://api.twitter.com/2/tweets',
  method: 'POST',
  // 将body hash加入签名参数,确保OAuth签名完整
  data: { oauth_body_hash: bodyHash },
};

const token = {
  key: '你的access token',
  secret: '你的access token secret',
};

const authHeader = oauth.toHeader(oauth.authorize(requestData, token));

console.log('tweeting');
console.log(JSON.stringify(authHeader));

const tweetResp = await fetch(requestData.url, {
  method: requestData.method,
  body: requestBody, // 传递JSON字符串格式的请求体
  headers: {
    ...authHeader,
    'Content-Type': 'application/json',
  },
});

// 修正状态码判断:Twitter创建成功返回201
if (tweetResp.status !== 201) {
  console.error('返回状态', tweetResp.status, tweetResp.statusText);
  const errorDetails = await tweetResp.json();
  console.error(JSON.stringify(errorDetails));
  throw new Error(JSON.stringify(errorDetails));
}

console.log('推文发送成功');
const result = await tweetResp.json();
console.log(result);

额外注意事项

  • 确保所有令牌(consumer key/secret、access token/secret)与Postman中使用的完全一致,无拼写错误或多余空格。
  • 若Lambda配置了VPC或代理,需确保网络能正常访问https://api.twitter.com。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 00:30:44