0
votes

Trying to make my expressJS app control users' google drive files. I've been utilizing the node 'googleapis' package. After following a slightly dated/incorrect article here, I've gotten the script to:

  • redirect a user to their authorization url
  • grab the 'code' from get parameter and then...
  • register it back as access tokens, which can then be used to...
  • create a registered 'auth' object

When I use this to create the drive object and try to get it to list files, I get the following error: 'Error: Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup'

This error has already popped up on SO question, and on github.

Following general advice, I re-enabled the drive api, re-downloaded access key. I've also tried replacing the sensitive drive scope a gmail scope, but that didn't work either. I'm not sure where else turn to start debugging at this point. I have a sneaking suspicion my entire auth object is being formed incorrectly but I can't find anything wrong.

This is the related piece of Express app code I'm using to create the authObject and then read drive files.

/**
 * Google Utility class that packages different actions related to authentication
 */
class GoogleUtil {
  constructor(secretFileName = 'client_secret.json') {
    const secret = JSON.parse(fs.readFileSync(secretFileName)).web;
    const { client_id, client_secret, redirect_uris } = secret;
    this.client_id = client_id;
    this.client_secret = client_secret;
    this.redirect_uri = redirect_uris[0];
    this.standardScope = [
      'https://www.googleapis.com/auth/drive',
      // 'https://www.googleapis.com/auth/gmail.readonly',
      // 'https://www.googleapis.com/auth/userinfo.profile'
    ];
  }

  createConnection() {
    return new google.auth.OAuth2(this.client_id, this.client_secret, this.redirect_uri); // form authObject
  }
  getConnectionUrl(auth) {
    return auth.generateAuthUrl({
      access_type: 'offline',
      prompt: 'consent',
      scope: this.standardScope
    });
  }
  async getAccessTokenFromCode(code) {
    var auth = this.createConnection();
    const data = await auth.getToken(code);
    return data.tokens;

  }
}
const g = new GoogleUtil();


/**
 * BEGIN ROUTE DEFINITIONS
 */

// THIS IS FIRST STEP. FRONTEND WILL REDIRECT TO GIVEN URL
app.get('/api/googleLoginUrl', async (req, res) => {
  const oAuth2Client = g.createConnection();
  const url = g.getConnectionUrl(oAuth2Client);
  res.json({ url });
});


// *****
// NOTE: THIS IS ROUTE THAT ATTEMPTS TO LIST FILES AND THROWS ERROR
// *****
app.get('/google-auth-redirect', async (req, res) => {
  if (!req.query.code) return res.send('Malformed request');

  const tokens = await g.getAccessTokenFromCode(req.query.code);
  const auth = g.createConnection().setCredentials(tokens);


  const drive = google.drive({ version: 'v3', auth: auth });
  drive.files.list({
    pageSize: 10,
    fields: 'nextPageToken, files(id, name)',
  }, (err, resp) => {
    if (err) return console.log('The API returned an error: ' + err);
    console.log(resp);
  });

  res.redirect('/');
});

In the google developer console, clicking on 'create credentials' in the drive API overview informs me that my current credentials are compatible. The project scopes do include ' ../auth/drive'.

I'd want it to be able to list files from an authenticated user's account.

1

1 Answers

0
votes

I think this might be related to how you are asking for permissions. If you are using your application to manipulate user's drive files you need a couple of things:

  1. Check you have the correct access scopes setup.
  2. Check you authentication parameter/Oauth screen is setup with said scopes.

You might want to read some documentation regarding authorizing users

Hope this helps! ;)