叽叽喳喳request_token端点总是返回“无法validation你”

我正在写一个简单的twitterlogin,并尝试获取请求令牌,以redirect用户访问令牌,但我总是以couldn't authenticate you错误,我试图添加签名作为最后的头,它不工作了。 当我删除一些头我得到错误的authentication数据错误,所以这个configuration我认为一切都是正确的我只是不能确定我做错了什么,叽叽喳喳拒绝发回请求令牌。

这是我的代码

 '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"); 

关键是双重逃逸basestring参数