我发现此函数用于生成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'
}
我尝试按照此处的建议对请求主体进行编码,但得到了相同的错误:
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时做错了什么,或者如何让它与twitterapiv2一起工作,有什么想法吗?
我怀疑这与请求的主体有关,因为这是两个请求之间的主要区别,但未能使其工作。
1条答案
按热度按时间6l7fqoea1#
请想一想,出于某种原因,请求主体不应包含在身份验证中: