Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Connecting to the Gmail IMAP API in javascript/node.js

I am trying to connect to gmail via its IMAP API. I am using Bruno Morency's node-imap library for that. For creating the oauth_signature, timestamp and nonce I use another library.

To be more specific: The ressource-owner has already authenticated the consumer. So I do have an access-token + secret. Of course I also have the consumer's secret+token. So what I want is to login with the XOAuth mechanism described here (heading: SASL Initial Client Request).

When executing the code I get an error:

Error while executing request: Invalid credentials d43if2188869web.36

I wonder what I am doing wrong. Actually there might be more reasons. Wrong base64 encoding (although encoding probably works right since you get a different error for different encoding, I am pretty sure this is not it), wrong signature calculating (UPDATE: I tested this now with http://oauth.net/core/1.0a/#sig_base_example), nonce calculating or others.

I can authenticate using the same credentials (consumer+ressource-owner) in a java app, so credentials are most probably not the cause of the error (just wrong encoding/signature calculating)

Finally the code. I omitted consumer's key+secret neither ressource owner's token+secret for obvious reasons).

var oauth_version = "1.0";
var oauth_timestamp = OAuth.timestamp();
var oauth_nonce = OAuth.nonce(6); //random nonce?

var oauth_consumer_key = "NOTFORYOU"; //validated
var oauth_consumer_secret = "NOTFORYOU"; //validated
var oauth_token = "NOTFORYOU"; //validated
var oauth_token_secret = "NOTFORYOU"; //validated
var email = "NOTFORYOU"; //validated

var oauth_signature_method = "HMAC-SHA1";
var method = "GET";
var action = "https://mail.google.com/b/"
    +email
    +"/imap/"; //gmail's request url

//signature
var oauth_signature_method = "HMAC-SHA1"; //from https://developers.google.com/google-apps/gmail/oauth_protocol

//example values for validating signature from     http://oauth.net/core/1.0a/#sig_base_example
oauth_consumer_key="dpf43f3p2l4k3l03";
oauth_nonce="kllo9940pd9333jh";
oauth_signature_method="HMAC-SHA1";
oauth_timestamp="1191242096";
oauth_token="nnch734d00sl2jdk";
oauth_version="1.0";
action="http://photos.example.net/photos?file=vacation.jpg&size=original";
method="GET";

//signature
var signature_basestring_parameters = {
    oauth_version: oauth_version
    , oauth_consumer_key: oauth_consumer_key
    , oauth_timestamp: oauth_timestamp
    , oauth_nonce: oauth_nonce
    , oauth_token: oauth_token
    , oauth_signature_method: oauth_signature_method
}

//var signature_basestring = oauth_consumer_key+"&"+oauth_token_secret;
var signature_basestring = OAuth.SignatureMethod.getBaseString({method: method, action: action, parameters: signature_basestring_parameters});

var methodName = oauth_signature_method;
var signer = OAuth.SignatureMethod.newMethod(methodName, {
                    consumerSecret: oauth_consumer_secret,
                    tokenSecret: oauth_token_secret
                }
                   );
console.log("signature_basestring=["+signature_basestring+"]");

var oauth_signature = signer.getSignature(signature_basestring);

console.log("oauth_signature=["+oauth_signature+"]");

oauth_signature=OAuth.percentEncode(oauth_signature);

console.log("(escaped) oauth_signature=["+oauth_signature+"]"); //prints out tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D as in the [example](http://oauth.net/core/1.0a/#sig_base_example)

//base-string
var baseStringDecoded =  "GET"
    + " "
    + "https://mail.google.com/b/"+email+"/imap/"
    + " "
    + "oauth_consumer_key=\""+oauth_consumer_key+"\","
    + "oauth_nonce=\""+oauth_nonce+"\","
    + "oauth_signature=\""+oauth_signature+"\","
    + "oauth_signature_method=\""+oauth_signature_method+"\","
    + "oauth_timestamp=\""+oauth_timestamp+"\","
    + "oauth_token=\""+oauth_token+"\","
    + "oauth_version=\""+oauth_version+"\"";

var baseString = Base64.encode(  //base64 from http://www.webtoolkit.info/javascript-base64.html
    baseStringDecoded
);


//create imap connection
var imap = new ImapConnection({
                  host: 'imap.gmail.com',
                  port: 993,
                  secure: true,
                  debug: true,
                  xoauth: baseString
              });

UPDATED: I found an example how to generate the base signature string. based on this I changed my code. Accordingly, now I get the same results for signature (generating base string for signature, calculating signature value, percent encoding signature value) as in the example. This means I am (i.e. the oauth library used) most probably calculating the oauth_signature in a right way and something else is going wrong.

like image 985
forste Avatar asked Mar 20 '12 22:03

forste


2 Answers

Finally I succeeded. My problem in the end was that I changed the key in oauth.js for testing the oauth example, changing it back did the job.

So the the example above should now work to authenticate on the gmail IMAP API

like image 91
forste Avatar answered Nov 15 '22 11:11

forste


If you think it's encoding related check out How to do Base64 encoding in node.js? for node's bas64 instead of webtoolkit.

like image 1
Krut Avatar answered Nov 15 '22 12:11

Krut