desmondmorris / node-twitter

Client library for the Twitter REST and Streaming API's.
https://www.npmjs.com/package/twitter
MIT License
1.27k stars 237 forks source link

Oauth/request_token page does not exist #307

Open skeddles opened 6 years ago

skeddles commented 6 years ago

Trying to authenticate users with twitter.

I'm creating a post request to oauth/request_token as described here. But I keep getting this error:

error: [ { message: 'Sorry, that page does not exist', code: 34 } ]

  const client = new Twitter({
    consumer_key: 'KwG9Ni37yZTooeiSGTqebNwzN',
    consumer_secret: 'BTOvEtUNYShtEdovNNDfwUwA85NO97cg4QQvn24TjCIsjofRr5',
    access_token_key: '775341332155944960-KV2dUCGWRTMs4XijgzkLAXBY92rTI3F',
    access_token_secret: 'jxDnVDKeTpP7N7oc0Mu4LM5nfkI21lyxEcMAVthbq3I6k'
  });

  var tokenData = {
    oauth_callback: "https://example.com/twitter_request_token"
  }

  client.post('oauth/request_token', tokenData, function (error, data, response) {
    if (error) return console.log('error:',error);

    console.log(data);

    res.redirect('https://api.twitter.com/oauth/authenticate?oauth_token='+data.oauth_token);
  });
zerotrickpony commented 6 years ago

TLDR I think this won't work; you need to use some other library (such as request) to get the request_token. More detail:

The first problem is that node-twitter prepends an API version string to the request path, which isn't wanted for the oauth URLs. So your code as written requests this:

https://api.twitter.com/1.1/oauth/request_token

...but you want this:

https://api.twitter.com/oauth/request_token

You can work around the issue by passing a full URL for the first argument to client.post(), which will override the built-in base URLs.

However, your next problem is that, contrary to the documentation, the request_token endpoint's response format isn't actually JSON, it's url-encoded form data. node-twitter assumes response bodies are always JSON and it crashes with a parse error.

I had to use request.js to get this working. Here's sample code:

    const request = require('request');
    const options = {
      headers: {
        Accept: '*/*',
        Connection: 'close',
        'User-Agent': 'node-twitter/1'
      },
      oauth: {
        consumer_key: MYKEY,
        consumer_secret: MYSECRET,
        token: MYAPPTOKEN,
        token_secret: MYAPPTOKENSECRET,
      },
      method: 'post',
      url: 'https://api.twitter.com/oauth/request_token',
      form: {
        'oauth_callback': MY_WHITELISTED_CALLBACK_URL,
      }
    };

    request(options, function(error, response, data) {
      console.log(data);
    });