Merge branch 'master' of https://github.com/meltingice/node-oauth into meltingice-master
Conflicts: Readme.md
This commit is contained in:
commit
c1c9270181
|
@ -1,21 +1,21 @@
|
|||
node-oauth
|
||||
===========
|
||||
A simple oauth API for node.js . This API allows users to authenticate against OAUTH providers, and thus act as OAuth consumers
|
||||
A simple oauth API for node.js . This API allows users to authenticate against OAUTH providers, and thus act as OAuth consumers. It also has support for OAuth Echo, which is used for communicating with 3rd party media providers such as TwitPic and yFrog.
|
||||
|
||||
Tested against both Twitter (http://twitter.com), term.ie (http://term.ie/oauth/example/) and Yahoo!
|
||||
Tested against Twitter (http://twitter.com), term.ie (http://term.ie/oauth/example/), TwitPic, and Yahoo!
|
||||
|
||||
Also provides rudimentary OAuth2 support, tested against facebook connect and github. For more complete usage examples please take a look
|
||||
at connect-auth (http://github.com/ciaranj/connect-auth)
|
||||
|
||||
If you're running a node.js version more recent than 0.4 then you will need to use a version of node-oauth greater than or equal to 0.9.0.
|
||||
If you're running a node.js version in the 0.2x stable branc, then you will need to use version 0.8.4.
|
||||
If you're running a node.js version in the 0.2x stable branch, then you will need to use version 0.8.4.
|
||||
|
||||
Please be aware that when moving from 0.8.x to 0.9.0 there are no major API changes your, I've bumped the semi-major version element
|
||||
so that I can release fixes to the 0.8.x stream if problems come out.
|
||||
|
||||
Change History
|
||||
==============
|
||||
* 0.9.1 - Added support for automatically following 302 redirects (Thanks neyric)
|
||||
* 0.9.1 - Added support for automatically following 302 redirects (Thanks neyric) Added support for OAuth Echo (Thanks Ryan LeFevre)
|
||||
* 0.9.0 - Compatibility fixes to bring node-oauth up to speed with node.js 0.4x [thanks to Rasmus Andersson for starting the work ]
|
||||
* 0.8.4 - Fixed issue #14 (Parameter ordering ignored encodings). Added support for repeated parameter names. Implements issue #15 (Use native SHA1 if available, 10x speed improvement!). Fixed issue #16 (Should use POST when requesting access tokens.). Fixed Issue #17 (OAuth2 spec compliance). Implemented enhancement #13 (Adds support for PUT & DELETE http verbs). Fixes issue #18 (Complex/Composite url arguments [thanks novemberborn])
|
||||
* 0.8.3 - Fixed an issue where the auth header code depended on the Array's toString method (Yohei Sasaki) Updated the getOAuthRequestToken method so we can access google's OAuth secured methods. Also re-implemented and fleshed out the test suite.
|
||||
|
@ -35,3 +35,4 @@ Contributors
|
|||
|
||||
* Ciaran Jessup - ciaranj@gmail.com
|
||||
* Mark Wubben - http://equalmedia.com/
|
||||
* Ryan LeFevre - http://meltingice.net
|
||||
|
|
1
index.js
1
index.js
|
@ -1,2 +1,3 @@
|
|||
exports.OAuth = require("./lib/oauth").OAuth;
|
||||
exports.OAuthEcho = require("./lib/oauth").OAuthEcho;
|
||||
exports.OAuth2 = require("./lib/oauth2").OAuth2;
|
46
lib/oauth.js
46
lib/oauth.js
|
@ -6,6 +6,8 @@ var crypto= require('crypto'),
|
|||
querystring= require('querystring');
|
||||
|
||||
exports.OAuth= function(requestUrl, accessUrl, consumerKey, consumerSecret, version, authorize_callback, signatureMethod, nonceSize, customHeaders) {
|
||||
this._echo = false;
|
||||
|
||||
this._requestUrl= requestUrl;
|
||||
this._accessUrl= accessUrl;
|
||||
this._consumerKey= consumerKey;
|
||||
|
@ -27,6 +29,26 @@ exports.OAuth= function(requestUrl, accessUrl, consumerKey, consumerSecret, vers
|
|||
"User-Agent" : "Node authentication"}
|
||||
};
|
||||
|
||||
exports.OAuthEcho= function(realm, verify_credentials, consumerKey, consumerSecret, version, signatureMethod, nonceSize, customHeaders) {
|
||||
this._echo = true;
|
||||
|
||||
this._realm= realm;
|
||||
this._verifyCredentials = verify_credentials;
|
||||
this._consumerKey= consumerKey;
|
||||
this._consumerSecret= this._encodeData( consumerSecret );
|
||||
this._version= version;
|
||||
|
||||
if( signatureMethod != "PLAINTEXT" && signatureMethod != "HMAC-SHA1")
|
||||
throw new Error("Un-supported signature method: " + signatureMethod );
|
||||
this._signatureMethod= signatureMethod;
|
||||
this._nonceSize= nonceSize || 32;
|
||||
this._headers= customHeaders || {"Accept" : "*/*",
|
||||
"Connection" : "close",
|
||||
"User-Agent" : "Node authentication"};
|
||||
}
|
||||
|
||||
exports.OAuthEcho.prototype = exports.OAuth.prototype;
|
||||
|
||||
exports.OAuth.prototype._getTimestamp= function() {
|
||||
return Math.floor( (new Date()).getTime() / 1000 );
|
||||
}
|
||||
|
@ -85,13 +107,18 @@ exports.OAuth.prototype._isParameterNameAnOAuthParameter= function(parameter) {
|
|||
// build the OAuth request authorization header
|
||||
exports.OAuth.prototype._buildAuthorizationHeaders= function(orderedParameters) {
|
||||
var authHeader="OAuth ";
|
||||
if (this._echo) {
|
||||
authHeader += 'realm="' + this._realm + '",';
|
||||
}
|
||||
|
||||
for( var i= 0 ; i < orderedParameters.length; i++) {
|
||||
// Whilst the all the parameters should be included within the signature, only the oauth_ arguments
|
||||
// should appear within the authorization header.
|
||||
if( this._isParameterNameAnOAuthParameter(orderedParameters[i][0]) ) {
|
||||
authHeader+= this._encodeData(orderedParameters[i][0])+"=\""+ this._encodeData(orderedParameters[i][1])+"\",";
|
||||
authHeader+= "" + this._encodeData(orderedParameters[i][0])+"=\""+ this._encodeData(orderedParameters[i][1])+"\",";
|
||||
}
|
||||
}
|
||||
|
||||
authHeader= authHeader.substring(0, authHeader.length-1);
|
||||
return authHeader;
|
||||
}
|
||||
|
@ -223,6 +250,9 @@ exports.OAuth.prototype._prepareParameters= function( oauth_token, oauth_token_s
|
|||
if( oauth_token ) {
|
||||
oauthParameters["oauth_token"]= oauth_token;
|
||||
}
|
||||
|
||||
var sig;
|
||||
if (!this._echo) {
|
||||
if( extra_params ) {
|
||||
for( var key in extra_params ) {
|
||||
oauthParameters[key]= extra_params[key];
|
||||
|
@ -246,7 +276,11 @@ exports.OAuth.prototype._prepareParameters= function( oauth_token, oauth_token_s
|
|||
}
|
||||
}
|
||||
|
||||
var sig= this._getSignature( method, url, this._normaliseRequestParams(oauthParameters), oauth_token_secret);
|
||||
sig = this._getSignature( method, url, this._normaliseRequestParams(oauthParameters), oauth_token_secret);
|
||||
} else {
|
||||
sig = this._getSignature( "GET", this._verifyCredentials, this._normaliseRequestParams(oauthParameters), oauth_token_secret);
|
||||
}
|
||||
|
||||
var orderedParameters= this._sortRequestParams( this._makeArrayOfArgumentsHash(oauthParameters) );
|
||||
orderedParameters[orderedParameters.length]= ["oauth_signature", sig];
|
||||
return orderedParameters;
|
||||
|
@ -263,7 +297,13 @@ exports.OAuth.prototype._performSecureRequest= function( oauth_token, oauth_toke
|
|||
if( parsedUrl.protocol == "https:" && !parsedUrl.port ) parsedUrl.port= 443;
|
||||
|
||||
var headers= {};
|
||||
headers["Authorization"]= this._buildAuthorizationHeaders(orderedParameters);
|
||||
var authorization = this._buildAuthorizationHeaders(orderedParameters);
|
||||
if (this._echo) {
|
||||
headers["X-Verify-Credentials-Authorization"]= authorization;
|
||||
} else {
|
||||
headers["Authorization"]= authorization;
|
||||
}
|
||||
|
||||
headers["Host"] = parsedUrl.host
|
||||
|
||||
for( var key in this._headers ) {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
var vows = require('vows'),
|
||||
assert = require('assert'),
|
||||
events = require('events'),
|
||||
OAuth= require('../lib/oauth').OAuth;
|
||||
OAuth= require('../lib/oauth').OAuth,
|
||||
OAuthEcho= require('../lib/oauth').OAuthEcho;
|
||||
|
||||
vows.describe('OAuth').addBatch({
|
||||
'When generating the signature base string described in http://oauth.net/core/1.0/#sig_base_example': {
|
||||
|
@ -124,6 +125,19 @@ vows.describe('OAuth').addBatch({
|
|||
assert.equal( oa.authHeader("http://somehost.com:3323/foo/poop?bar=foo", "token", "tokensecret"), 'OAuth oauth_consumer_key="consumerkey",oauth_nonce="ybHPeOEkAUJ3k2wJT9Xb43MjtSgTvKqp",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1272399856",oauth_token="token",oauth_version="1.0",oauth_signature="zeOR0Wsm6EG6XSg0Vw%2FsbpoSib8%3D"');
|
||||
}
|
||||
},
|
||||
'When get the OAuth Echo authorization header': {
|
||||
topic: function () {
|
||||
var realm = "http://foobar.com/";
|
||||
var verifyCredentials = "http://api.foobar.com/verify.json";
|
||||
var oa = new OAuthEcho(realm, verifyCredentials, "consumerkey", "consumersecret", "1.0A", "HMAC-SHA1");
|
||||
oa._getTimestamp= function(){ return "1272399856"; }
|
||||
oa._getNonce= function(){ return "ybHPeOEkAUJ3k2wJT9Xb43MjtSgTvKqp"; }
|
||||
return oa;
|
||||
},
|
||||
'Provide a valid signature when a token and token secret is present': function (oa) {
|
||||
assert.equal( oa.authHeader("http://somehost.com:3323/foo/poop?bar=foo", "token", "tokensecret"), 'OAuth realm="http://foobar.com/",oauth_consumer_key="consumerkey",oauth_nonce="ybHPeOEkAUJ3k2wJT9Xb43MjtSgTvKqp",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1272399856",oauth_token="token",oauth_version="1.0A",oauth_signature="0rr1LhSxACX2IEWRq3uCb4IwtOs%3D"');
|
||||
}
|
||||
},
|
||||
'When non standard ports are used': {
|
||||
topic: function() {
|
||||
var oa= new OAuth(null, null, null, null, null, null, "HMAC-SHA1"),
|
||||
|
|
Loading…
Reference in New Issue