Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

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

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

Problem

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.

Problem courtesy of: forste

Solution

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

Solution courtesy of: forste

Discussion

View additional discussion.



This post first appeared on Node.js Recipes, please read the originial post: here

Share the post

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

×

Subscribe to Node.js Recipes

Get updates delivered right to your inbox!

Thank you for your subscription

×