node.js oauth-1.0a 适用于 Twitter API v1.1 但不适用于 v2
Posted
技术标签:
【中文标题】node.js oauth-1.0a 适用于 Twitter API v1.1 但不适用于 v2【英文标题】:node.js oauth-1.0a working for Twitter API v1.1 but not for v2 【发布时间】:2021-09-20 14:16:43 【问题描述】:我有found这个函数来生成oauth-1.0a头:
// auth.js
const crypto = require("crypto");
const OAuth1a = require("oauth-1.0a");
function auth(request)
const oauth = new OAuth1a(
consumer:
key: process.env.TWITTER_API_KEY,
secret: process.env.TWITTER_API_SECRET_KEY,
,
signature_method: "HMAC-SHA1",
hash_function(baseString, key)
return crypto.createHmac("sha1", key).update(baseString).digest("base64");
,
);
const authorization = oauth.authorize(request,
key: process.env.TWITTER_ACCESS_TOKEN,
secret: process.env.TWITTER_ACCESS_TOKEN_SECRET,
);
return oauth.toHeader(authorization).Authorization;
module.exports = auth;
如果我用 Twitter API v1.1 试试,效果很好:
// v1.js
require("dotenv").config();
const axios = require("axios");
const auth = require("./auth");
const url = "https://api.twitter.com/1.1/favorites/create.json";
const method = "POST";
const params = new URLSearchParams(
id: "1397568983931392004",
);
axios
.post(url, undefined,
params,
headers:
authorization: auth(
method,
url: `$url?$params`,
),
,
)
.then((data) =>
return console.log(data);
)
.catch((err) =>
if (err.response)
return console.log(err.response);
console.log(err);
);
但如果我尝试使用 Twitter API v2:
// v2.js
require("dotenv").config();
const axios = require("axios");
const auth = require("./auth");
const url = `https://api.twitter.com/2/users/$process.env.TWITTER_USER_ID/likes`;
const method = "POST";
const data =
tweet_id: "1397568983931392004",
;
axios
.post(url, data,
headers:
authorization: auth(
method,
url,
data,
),
,
)
.then((data) =>
return console.log(data);
)
.catch((err) =>
if (err.response)
return console.log(err.response);
console.log(err);
);
它失败了:
title: 'Unauthorized',
type: 'about:blank',
status: 401,
detail: 'Unauthorized'
我尝试按照here 的建议对请求正文进行编码,但得到了同样的错误:
require("dotenv").config();
const axios = require("axios");
const auth = require("./auth");
const querystring = require("querystring");
const url = `https://api.twitter.com/2/users/$process.env.TWITTER_USER_ID/likes`;
const method = "POST";
const data = percentEncode(
querystring.stringify(
tweet_id: "1397568983931392004",
)
);
function percentEncode(string)
return string
.replace(/!/g, "%21")
.replace(/\*/g, "%2A")
.replace(/'/g, "%27")
.replace(/\(/g, "%28")
.replace(/\)/g, "%29");
axios
.post(url, data,
headers:
"content-type": "application/json",
authorization: auth(
method,
url,
data,
),
,
)
.then((data) =>
return console.log(data);
)
.catch((err) =>
if (err.response)
return console.log(err.response);
console.log(err);
);
如果使用 Postman 进行测试,两个端点(1.1 和 2)使用相同的凭据都可以正常工作。
关于我在使用 v2 时做错了什么或如何让它与 Twitter API v2 一起工作的任何想法?
我怀疑这与请求的主体有关,因为这是两个请求之间的主要区别,但无法使其工作。
【问题讨论】:
您的应用是否属于可以访问 API v2 的项目? 是的,我已经用邮递员和作品进行了测试,包括 V1.1 和 V2,但这种方式并没有并且想要弄清楚。 @MauricioRobayo 我遇到了类似的问题,有人可以告诉我如何解决吗?问题链接:twittercommunity.com/t/how-to-use-twitter-v2-apis/163669 【参考方案1】:弄清楚,生成授权标头时不应包含请求的正文:
require("dotenv").config();
const axios = require("axios");
const auth = require("./auth");
const url = `https://api.twitter.com/2/users/$process.env.TWITTER_USER_ID/likes`;
const method = "POST";
const data =
tweet_id: "1397568983931392004",
;
axios
.post(url, data,
headers:
authorization: auth(
method,
url,
),
,
)
.then((data) =>
return console.log(data);
)
.catch((err) =>
if (err.response)
return console.log(err.response);
console.log(err);
);
基本上,在向 Twitter API v1.1 发出 post 请求时,数据应该被编码,应该用于生成授权标头,并且 post 请求应该以application/x-www-form-urlencoded
发送。
向 Twitter API v2 发出 post 请求时,数据不应编码,不应包含在生成授权标头时,并且必须以 application/json
发送。
希望这对其他人有所帮助。
【讨论】:
以上是关于node.js oauth-1.0a 适用于 Twitter API v1.1 但不适用于 v2的主要内容,如果未能解决你的问题,请参考以下文章
适用于 Amazon SES 的 Node.js 模块 [关闭]
适用于 Windows/Node 0.8 的 Node.js 键值存储