Google OAuth with Node.js

04 Feb 2018 in Tech

I've been working on an Alexa skill that needed access to my Google Calendar account. The provided quick start is a little tough to follow, so I worked through it and created a minimal example that generates an auth token and writes it to disk.

You'll need to install the google-auth-library first. Make sure that you're installing at least version 1.0.0 (the quick start installs 0.9 which doesn't work with the new Google SDK)

bash
npm install google-auth-library@^1.0.0 --save

Once that's installed, you'll need to create some OAuth credentials to used. Follow these instructions, taken from the quick start:

  1. Use this wizard to create or select a project in the Google Developers Console and automatically turn on the API. Click Continue, then Go to credentials.
  2. On the Add credentials to your project page, click the Cancel button.
  3. At the top of the page, select the OAuth consent screen tab. Select an Email address, enter a Product name if not already set, and click the Save button.
  4. Select the Credentials tab, click the Create credentials button and select OAuth client ID.
  5. Select the application type Other, enter the name "Google Calendar API Quickstart", and click the Create button.
  6. Click OK to dismiss the resulting dialog.
  7. Click the file_download (Download JSON) button to the right of the client ID.
  8. Move this file to your working directory and rename it client_secret.json.

Next, you need to use those secrets to generate an access token. Create a file named auth.js with the following contents (we're accessing Google Calendar, but you can update SCOPES to contain anything you need).

javascript
var fs = require("fs");
var readline = require("readline");
var googleAuth = require("google-auth-library");
var SCOPES = ["https://www.googleapis.com/auth/calendar.readonly"];
var TOKEN_DIR =
(process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE) +
"/.credentials/";
var TOKEN_PATH = TOKEN_DIR + "calendar-nodejs-quickstart.json";
// We need things such as our client ID and secret, which we can read from a file
const googleSecrets = JSON.parse(
fs.readFileSync("client_secret.json")
).installed;
// Create an OAuth2 client which we use to generate an auth URL
// and exchange the code for a token
var oauth2Client = new googleAuth.OAuth2Client(
googleSecrets.client_id,
googleSecrets.client_secret,
googleSecrets.redirect_uris[0]
);
// Generate an authentication URL for us to visit
var authUrl = oauth2Client.generateAuthUrl({
access_type: "offline",
scope: SCOPES,
});
console.log("Authorize this app by visiting this url: ", authUrl);
// Once we have a token, save it
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question("Enter the code from that page here: ", function (code) {
rl.close();
oauth2Client.getToken(code, function (err, token) {
if (err) {
console.log(
"Error while trying to retrieve access token:",
err.response.data.error_description
);
return;
}
try {
fs.mkdirSync(TOKEN_DIR);
} catch (err) {
if (err.code != "EEXIST") {
throw err;
}
}
fs.writeFileSync(TOKEN_PATH, JSON.stringify(token));
console.log("Your credentials have been written to", TOKEN_PATH);
});
});

Run node auth.js and visit the URL that's generated. Once you have a code, enter it in to the terminal and press enter. You should now have an access token saved to disk at ~/.credentials/calendar-nodejs-quickstart.json.