Martin Bramwell
Martin Bramwell

Reputation: 2111

Authenticated ok with passport-google-oauth but can't access any API

Using passport in my microservice I can successfully authorize my endpoints to multiple Google users.

The next step ought be to write to Google Sheets but I cannot get any results and cannot find any worked through example of how to do it.

import gapis from 'googleapis';
import { OAuth2Client } from 'google-auth-library';

app.get('/report',
    passport.authenticate(['jwt'], { session: false }),
    (req, res) => {

        const secrets = getSecrets();
        const oauth2Client = new OAuth2Client(
            secrets.GOOGLE_CLIENTID,
            secrets.GOOGLE_CLIENTSECRET,
            secrets.GOOGLE_REDIRECT_URI
        );
        const creds = {
            access_token: req.user.providers[0].tkn,
            refresh_token: ''
        }
        oauth2Client['credentials'] = creds;

        gapis.sheets('v4').spreadsheets.values.get({
            auth: oauth2Client,
            spreadsheetId: '1NITk258-perOnxMk?????????????????M1J82kcEk',
            range: 'Report!A1:G50',
        }, function(err, response) {
            if (err) {
              console.log('The API returned an error: ' + err);
              return;
            }
            if ( response ) {
                var rows = response.values;
                if ( rows && rows.length > 0) {
                  console.log('Report Data');
                  for (var i = 0; i < rows.length; i++) {
                    var row = rows[i];
                    console.log('%s, %s', row[0], row[4]);
                  }
                } else {
                  console.log('No data found.');
                }
            } else {
              console.log('Got no response at all.');
            }
        });
        res.send('Secure response from ' + JSON.stringify(req.user));
    }
);

When I call that endpoint, the browser page correctly shows ...

Secure response from {"name":"Dilbert","email":"dilbert@gma .....

... but, the server logs show :

The API returned an error: Error: No refresh token is set.

Obviously, I should be providing a refresh_token, but passport-google-oauth does not seem to return one!

passport.use(
  new passportGoogle.OAuth2Strategy( passportConfig, (accessToken, refreshToken, profile, done) => {

    console.log('* * * Google : Create Member : '); //  * * * Google : Create Member : 
    console.log( accessToken );  // ya29.GlxRBVEyXnMedqHBifJ-kSvrojGCpKk... etc
    console.log( refreshToken );  // undefined

Is SSO somehow incompatible with API access? If not, are they two entirely separate capabilities that cannot be handled in a single step?

Do I need to run OAuth twice, once to create the user and get an initial authorization token and then a second time to get a second authorization token for API access to their data?

Google describes various techniques for authenticating/authorizing access to their APIs: JWT, API Key, etc. What is the name of the correct one to use in this case?

If it helps to understand what I am trying to do ... my requirement is to allow numerous users to connect and then on their behalf manage several different Google Sheets in each user's private Drive space. This seems like a common use case, but I have yet to find a trustworthy recent tutorial or code example that shows it working.

Update : @chris-h got me the right answer, but it did not work immediately. I had to open Google's management page Apps with access to your account, find my microservice and Remove Access

Upvotes: 0

Views: 535

Answers (1)

Chris H
Chris H

Reputation: 511

See the following to get the refreshToken https://github.com/jaredhanson/passport/issues/42

Upvotes: 1

Related Questions