The Introduction to OAuth with Node.js mini-book is getting close to the release. The manuscript is ready. Now we’re putting final touches on the cover design and doing a second pass of editing.
Recently we had to work on modification to accommodate Twitter API v1.1. The main difference between Twitter API v1.1 and, soon to be deprecated, Twitter API v1.0 is that most of the REST API endpoints now require user or application context. In other words, each call needs to be performed via OAuth 1.0A or OAuth 2.0 authentication.
Recently we had to work on modification to accommodate Twitter API v1.1. The main difference between Twitter API v1.1 and, soon to be deprecated, Twitter API v1.0 is that most of the REST API endpoints now require user or application context. In other words, each call needs to be performed via OAuth 1.0A or OAuth 2.0 authentication.
At Storify we run everything on Node.js so it was natural that we used oauth module by Ciaran Jessup: NPM and GitHub. It’s mature and supports all the needed functionality but lacks any kind of examples and/or interface documentation.
Here are the examples of calling Twitter API v1.1, and a list of methods. I hope that nobody will have to dig through the oauth module source code anymore!
OAuth 1.0
Let start with a good old OAuth 1.0A. You’ll need four values to make this type of a request to Twitter API v1.1 (or any other service):
Your Twitter application key, a.k.a., consumer key
Your Twitter secret key
User token for your app
User secret for your app
All four of them can be obtained for your own apps at dev.twitter.com. In case that the user is not youself, you’ll need to perform 3-legged OAuth, or Sign in with Twitter, or something else.
Next we create oauth object with parameters, and call get() function to fetch a secured resource. Behind the scene get() function constructs unique values for the request header — Authorization header. The method encrypts URL, timestamp, application and other information in a signature. So the same header won’t work for another URL or after a specific time window.
var OAuth = require('OAuth');
var oauth = new OAuth.OAuth(
'https://api.twitter.com/oauth/request_token',
'https://api.twitter.com/oauth/access_token',
'your Twitter application consumer key',
'your Twitter application secret',
'1.0A',
null,
'HMAC-SHA1'
);
oauth.get(
'https://api.twitter.com/1.1/trends/place.json?id=23424977',
'your user token for this app',
//you can get it at dev.twitter.com for your own apps
'your user secret for this app',
//you can get it at dev.twitter.com for your own apps
function (e, data, res){
if (e) console.error(e);
console.log(require('util').inspect(data));
done();
});
});
OAuth Echo
OAuth Echo is similar to OAuth 1.0. If you’re a Delegator (service to which requests to Service Provider are delegated by Consumer) all you need to do is just pass the value of x-verify-credentials-authorization header to the Service Provider in Authorization header. Twitter has a good graphics on OAuth Echo.
There is OAuthEcho object which inherits must of its methods from normal OAuth class. In case if you want to write Consumer code (or for functional tests, in our case Storify is the delegator) and you need x-verify-credentials-authorization/Authorization header values, there is a authHeader method. If we look at it, we can easily reconstruct the headers with internal methods of oauth module such as _prepareParameters() and _buildAuthorizationHeaders(). Here is a function that will give us required values based on URL (remember that URL is a part of Authorization header):
function getEchoAuth(url) {
//helper to construct echo/oauth headers from URL
var oauth = new OAuth('https://api.twitter.com/oauth/request_token',
'https://api.twitter.com/oauth/access_token',
"AAAAAAAAAAAAAAAAAAAA",
//test app token
"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
//test app secret
'1.0A',
null,
'HMAC-SHA1');
var orderedParams = oauth._prepareParameters(
"1111111111-AAAAAA", //test user token
"AAAAAAAAAAAAAAAAAAAAAAA", //test user secret
"GET",
url
);
return oauth._buildAuthorizationHeaders(orderedParams);
}
From your consumer code you can maker request with superagent or other http client library (e.g., node.js core http module’s http.request):
var request = require('super agent');
request.post('your delegator api url')
.send({...})
//your json data
.set(
'x-auth-service-provider',
'https://api.twitter.com/1.1/account/verify_credentials.json')
.set(
'x-verify-credentials-authorization',
getEchoAuth("https://api.twitter.com/1.1/account/verify_credentials.json"))
.end(function(res){console.log(res.body)});
var OAuth2 = OAuth.OAuth2;
var twitterConsumerKey = 'your key';
var twitterConsumerSecret = 'your secret';
var oauth2 = new OAuth2(
twitterconsumerKey,
twitterConsumerSecret,
'https://api.twitter.com/',
null,
'oauth2/token',
null);
oauth2.getOAuthAccessToken(
'',
{'grant_type':'client_credentials'},
function (e, access_token, refresh_token, results){
console.log('bearer: ',access_token);
oauth2.get('protected url',
access_token, function(e,data,res) {
if (e) return callback(e, null);
if (res.statusCode!=200)
return callback(new Error(
'OAuth2 request failed: '+
res.statusCode),null);
try {
data = JSON.parse(data);
}
catch (e){
return callback(e, null);
}
return callback(e, data);
});
});
Please note the JSON.parse() function, oauth module returns string, not a JavaScript object.
Consumers of OAuth2 don’t need to fetch the bearer/access token for every request. It’s okay to do it once and save value in the database. Therefore, we can make requests to protected resources (i.e. Twitter API v.1.1) with only one secret password. For more information check out Twitter application only auth.
Node.js oauth API
Node.js oauth OAuth
oauth.OAuth()
Parameters:
requestUrl
accessUrl
consumerKey
consumerSecret
version
authorize_callback
signatureMethod
nonceSize
customHeaders
Node.js oauth OAuthEcho
oauth.OAuthEcho()
Parameters:
realm
verify_credentials
consumerKey
consumerSecret
version
signatureMethod
nonceSize
customHeaders
OAuthEcho sharers the same methods as OAuth
Node.js oauth Methods
Secure HTTP request methods for OAuth and OAuthEcho classes:
The authors of node.js oauth did a great job but currently there are 32 open pull requests (mine is one of them) and it makes me sad. Please let them know that we care about improving Node.js ecosystem of modules and developers community!