如何解决node.js oauth-1.0a 适用于 Twitter API v1.1 但不适用于 v2
我是 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,})
.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,{
headers: {
"content-type": "application/json",authorization: auth({
method,})
.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 一起工作的任何想法?
我怀疑这与请求正文有关,因为这是两个请求之间的主要区别,但一直无法使其工作。
解决方法
弄清楚,生成授权头时不应包含请求正文:
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 发出发布请求时,数据不应被编码,不应在生成授权标头时包含在内,并且必须作为 application/json
发送。
希望这对其他人有所帮助。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。