Paul S Chapman
Paul S Chapman

Reputation: 832

invalid_request from getToken in Javascript from Node.js

I have the following code in a node.js server application

app.get('/AuthorizeGoogle.html',function(req,res) {
    var auth        = new googleapis.OAuth2Client(config.google_login.client_id, config.google_login.client_secret, config.google_login.redirect_uri);
    var queryData   = url.parse(req.url,true).query;
    var code        = encodeURIComponent(queryData.code);

    console.log('Authorization Request recieved ');;

    console.log('Retrieiving token');
    auth.getToken(code,function(err,tokens) {
        console.log('Retrievied token ');
        console.log(tokens);
        console.log('**** ERROR ****');
        console.log(err);

        console.log('Calling setCredentials');
        auth.setCredentials(tokens);
        console.log('*****FINISHED!!!!!');
    });

    res.send('Authorization recieved ' + queryData.code)
});

This is called when Google returns and the user has authorised access to their Google account.

I get a code. However when auth.getToken() I am getting invalid_request. I have done this successfully in C#, but I am now moving to more open source tools hence moving the project to Node.js

Thanks in advance

OK - I looked again at the page suggested and did some refactoring of my code and that worked. I think what may have been the problem was the Url used to get the token in the first place.

I was already initialising the oauth2Client

var OAuth2Client = googleapis.OAuth2Client;
var oauth2Client;
oauth2Client    = new OAuth2Client(config.google_login.client_id, config.google_login.client_secret, config.google_login.redirect_uri);

The required Client Id, secret and redirect Url have been defined in a configuration file

So first all I changed the way I was generating that url. First off I set the Url to Login to Google to GoogleLogin.html which executes the following when the server receives a request for this page.

app.get('/GoogleLogin.html',function(req,res) {
    var scopes = "";

    // retrieve google scopes
    scopes += config.google_login.scopes.baseFeeds + " "
    scopes += config.google_login.scopes.calendar + " "
    scopes += config.google_login.scopes.drive + " "
    scopes += config.google_login.scopes.driveMetadata + " "
    scopes += config.google_login.scopes.profile + " "
    scopes += config.google_login.scopes.email + " "
    scopes += config.google_login.scopes.tasks

    var url = oauth2Client.generateAuthUrl({
        access_type: 'offline',
        scope: scopes
    });

    res.writeHead(302, {location: url});
    res.end();


});

This first building a string of the scopes then generating the Authorization Url before redirecting to the generated url

When Google redirects back to the site the following is executed

app.get('/AuthorizeGoogle.html',function(req,res) {
    // var auth = new googleapis.OAuth2Client(config.google_login.client_id,config.google_login.client_secret, config.google_login.redirect_uri);
    var queryData   = url.parse(req.url,true).query;
    var code        = queryData.code;

    console.log('Authorization Request recieved ');;

    console.log('Retrieving token');
    oauth2Client.getToken(code,function(err,tokens) {
        console.log('Retrieved token ');
        console.log(tokens);
        console.log('**** ERROR ****');
        console.log(err);

        console.log('Calling setCredentials');
        oauth2Client.setCredentials(tokens);
        console.log('*****FINISHED!!!!!');
    });

    res.send('Authorization recieved ' + queryData.code)
});

And this is now returning the Token and Refresh token correctly. Since it is the same code the only thing I can was wrong was the original call to Google.

Upvotes: 1

Views: 1568

Answers (1)

Steve
Steve

Reputation: 1309

I think your best bet would be to research what is done in the following github example: https://github.com/google/google-api-nodejs-client/blob/master/examples/oauth2.js

Upvotes: 2

Related Questions