Twitter的request_token端点总是返回“无法验证您”的消息。

6
我正在编写一个简单的 Twitter 登录,并尝试获取请求令牌以便将用户重定向到访问令牌,但我总是遇到“无法验证您”的错误。我尝试在最后一个标头中添加签名,但也没有起作用。当我删除一些标头时,会出现“坏的身份验证数据”错误,因此在这种配置下,我假设一切都正确,只是无法弄清楚我做错了什么,而 Twitter 拒绝发送请求令牌。
以下是我的代码:
'use strict';
const https = require("https");
const cfg = require('./config');
// const cfg=require(`${__dirname}/config`);
const qs = require("querystring");
const esc = qs.escape;
const crypto = require('crypto');
const HMAC = crypto.createHmac;
class twitter {
    constructor(o) {
        // if (!o || !o.consumer_key || !o.consumer_secret) throw new Error("Missing Paramaters");
        this.id = o.consumer_key;
        this.secret = o.consumer_secret;
    }
    getNonce() {
        let num = 32;
        let preDefined = Date.now().toString().split("");
        num -= preDefined.length;
        while (num--) {
            preDefined.push(Math.round(Math.random() * 31).toString(32));
        }
        return (new Buffer(preDefined.join("")).toString("base64"));
    }
    getSignature(HTTPmethod, url, parameters, tokenSecret) {
        const method = HTTPmethod.toUpperCase();
        const baseUrl = url;
        const params = parameters;
        const sorted = Object.keys(params).sort();
        let baseString = `${esc(method)}&${esc(baseUrl)}`;
        let signingKey = `${esc(this.secret)}&`
        signingKey += tokenSecret ? esc(tokenSecret) : "";
        let firstRun = true;
        sorted.forEach(param => {
            if (firstRun) {
                baseString += "&";
                firstRun = false;
            }
            else {
                baseString += esc("&");
            }
            baseString += esc(`${param}=${params[param]}`);
        });
        return HMAC('SHA1', signingKey).update(baseString).digest('base64');
        // return baseString;
    }
    getHeaders(httpMethod, baseUrl, additional, token, tokenSecret, extraHeaders) {
        let headers = {
            oauth_consumer_key: this.id,
            oauth_nonce: this.getNonce(),
            oauth_signature_method: "HMAC-SHA1",
            oauth_timestamp: Math.floor(Date.now() / 1000),
            oauth_version: "1.0"
        }
        if (extraHeaders) {
            for (let i in extraHeaders) {
                headers[i] = extraHeaders[i];
            }
        }
        if (token) headers.oauth_token = token;
        let params = headers;
        if (additional) {
            for (let i in additional) {
                params[i] = additional[i];
            }
        }
        // const signature = this.getSignature(httpMethod, baseUrl, params, tokenSecret || "");
        headers.oauth_signature = this.getSignature(httpMethod, baseUrl, params, tokenSecret || "");
        let header = `OAuth `;
        let firstRun = true;
        const sorted = Object.keys(headers).sort();
        sorted.forEach(i => {
            let prefix;
            if (firstRun) {
                prefix = "";
                firstRun = false;
            }
            else {
                prefix = ", ";
            }
            header += `${prefix}${esc(i)}="${esc(headers[i])}"`
        });
        // header += `, oauth_signature="${esc(signature)}"`;
        return header;
    }
    getRequestToken(cb) {
        if (!cb) throw new Error('callback must be defined');
        const callbackUrl = cb;
        let headers = this.getHeaders("POST", "https://api.twitter.com/oauth/request_token", false, false, false, {
            oauth_callback: callbackUrl
        });
        const reqParams = {
            method: "POST",
            host: "api.twitter.com",
            path: "/oauth/request_token",
            headers: { "Authorization": headers }
        }
        const req = https.request(reqParams, res => {
            let data = "";
            res.on("data", d => data += d);
            res.on("end", _ => console.log(data));
        }); req.end();
        console.log(req._headers);
    }
}
(new twitter({
    consumer_key: cfg.id,
    consumer_secret: cfg.secret
})).getRequestToken("https://127.0.0.1/twitter");
1个回答

3

关键在于双重转义基本字符串参数


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接