diff --git a/index.js b/index.js index 6482f77..5122dc1 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,6 @@ var crypto = require('crypto') + , url = require('url') + ; function sha (key, body, algorithm) { return crypto.createHmac(algorithm, key).update(body).digest('base64') @@ -8,6 +10,17 @@ function rsa (key, body) { return crypto.createSign('RSA-SHA1').update(body).sign(key, 'base64') } +function excludeDefaultPort (base_uri) { + var parsed = url.parse(base_uri); + if (parsed.port) { + if ((parsed.protocol == "http:" && parsed.port == "80") + || (parsed.protocol == "https:" && parsed.port == "443")) { + parsed.host = parsed.hostname; + } + } + return url.format(parsed); +} + function rfc3986 (str) { return encodeURIComponent(str) .replace(/!/g,'%21') @@ -45,6 +58,10 @@ function generateBase (httpMethod, base_uri, params) { // adapted from https://dev.twitter.com/docs/auth/oauth and // https://dev.twitter.com/docs/auth/creating-signature + // Exclude HTTPS for port 443, HTTP for port 80 + // https://tools.ietf.org/html/rfc5849#section-3.4.1.2 + var newBaseUri = excludeDefaultPort (base_uri) + // Parameter normalization // http://tools.ietf.org/html/rfc5849#section-3.4.1.3.2 var normalized = map(params) @@ -69,7 +86,7 @@ function generateBase (httpMethod, base_uri, params) { var base = [ rfc3986(httpMethod ? httpMethod.toUpperCase() : 'GET'), - rfc3986(base_uri), + rfc3986(newBaseUri), rfc3986(normalized) ].join('&') diff --git a/test.js b/test.js index 628515e..55983eb 100644 --- a/test.js +++ b/test.js @@ -105,11 +105,25 @@ var accsign = hmacsign('POST', 'https://api.twitter.com/oauth/access_token', , oauth_verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY' , oauth_version: '1.0' }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98", "x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA") - + console.log(accsign) console.log('PUw/dHA4fnlJYM6RhXk5IU/0fCc=') assert.equal(accsign, 'PUw/dHA4fnlJYM6RhXk5IU/0fCc=') +var accsign2 = hmacsign('POST', 'https://api.twitter.com:443/oauth/access_token', +{ oauth_consumer_key: 'GDdmIQH6jhtmLUypg82g' +, oauth_nonce: '9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8' +, oauth_signature_method: 'HMAC-SHA1' +, oauth_token: '8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc' +, oauth_timestamp: '1272323047' +, oauth_verifier: 'pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY' +, oauth_version: '1.0' +}, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98", "x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA") + +console.log(accsign2) +console.log('PUw/dHA4fnlJYM6RhXk5IU/0fCc=') +assert.equal(accsign2, 'PUw/dHA4fnlJYM6RhXk5IU/0fCc=') + var upsign = hmacsign('POST', 'http://api.twitter.com/1/statuses/update.json', { oauth_consumer_key: "GDdmIQH6jhtmLUypg82g" , oauth_nonce: "oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y" @@ -124,6 +138,20 @@ console.log(upsign) console.log('yOahq5m0YjDDjfjxHaXEsW9D+X0=') assert.equal(upsign, 'yOahq5m0YjDDjfjxHaXEsW9D+X0=') +var upsign2 = hmacsign('POST', 'http://api.twitter.com:80/1/statuses/update.json', + { oauth_consumer_key: "GDdmIQH6jhtmLUypg82g" + , oauth_nonce: "oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y" + , oauth_signature_method: "HMAC-SHA1" + , oauth_token: "819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw" + , oauth_timestamp: "1272325550" + , oauth_version: "1.0" + , status: 'setting up my twitter 私のさえずりを設定する' + }, "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98", "J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA") + +console.log(upsign2) +console.log('yOahq5m0YjDDjfjxHaXEsW9D+X0=') +assert.equal(upsign2, 'yOahq5m0YjDDjfjxHaXEsW9D+X0=') + // handle objects in params (useful for Wordpress REST API) var upsign = hmacsign('POST', 'http://wordpress.com/wp-json', { oauth_consumer_key: "GDdmIQH6jhtmLUypg82g"