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
相关产品推荐
相关产品推荐

