Google Authentication & Authorization via Oauth in 2022

I feel like I’ve had the misfortune of re-learning this topic over and over so I’ll document the process this time. Besides, since google is discontinuing Google Sign-In, I have to do a new implementation anyway.

We are discontinuing the Google Sign-In JavaScript Platform Library for web. Beginning April 30th, 2022 new web applications must use the Google Identity Services library, existing web apps may continue using the Platform Library until the March 31, 2023 deprecation date. For authentication and user sign-in, use the new Google Identity Services SDKs for both Web and Android instead.

So, “Google Sign-In” is discontinued and the newer library is called “Sign In With Google.” I guess you’ve got to rename it, so why not just change the order of the words? Done.

Ok, why the change? First, they sight improved security, lower friction between sign-in and sign-up, and a more consistent experience across the web. The later likely has to do with Chrome browser sessions, and also the ability to notice that google users are already signed into google, when they happen to be on other websites.

Previously my team didn’t use google libraries directly, but relied on Passport for authentication, and direct REST calls for authorization and API access. Now though, we are moving to using google’s provided web javascript client, https://accounts.google.com/gsi/client, and their Nodejs client, https://github.com/googleapis/google-api-nodejs-client

If you happen to be using apis.google.com/js/api.js, apis.google.com/js/client.js, or apis.google.com/js/platform.js, it’s time to update to the newer, Google Identity Services

In this guide, we will focus on “Sign In with Google” for Authentication, basically allowing a user to say who they are for sign-in/sign-up, and for Authorization with OAUTH2 tokens, which allows users access to Google Services like Drive, Calendar, etc.

If you only need to use Google for Authentication, you should follow this guide:

https://developers.google.com/identity/gsi/web/guides/migration

you’ll find a client button code generator here:

https://developers.google.com/identity/gsi/web/tools/configurator

Besides what Google mentions above, if you direct the login to call your backend serve, it is via a POST operation, and includes a JWT with all user info.

If you infact need both Authentication and Aurhorization you will follow this guide:

https://developers.google.com/identity/oauth2/web/guides/migration-to-gis

The client code is similar to the the Authentication code above, however unlike using data attributes in the sign in button, you’ll be setting parameters in javascript, for example you’ll include a “scopes” array. A difference on the server-side callback request is that it is a GET operation, and unlike getting user profile information (like email, full name, etc), you’ll need to specifically request ‘https://www.googleapis.com/auth/userinfo.profile’ and ‘https://www.googleapis.com/auth/userinfo.email’ scopes.

The GET request will contain an query parameter called code, which you will use to get your access token, refresh token (assuming you requested offline access), and user info (assuming you included the above scopes) via id_token. To decode the id_token which is in JWT format, you can call the verifyIdToken method of the oauth2Client object. Here’s a look how to handle the callback:

async function authCB(req, resp) {
  if (req.query.error) {
    return resp.send(req.query.error);
  }
  const { tokens } = await oauth2Client.getToken(req.query.code);
  const userInfo = (
    await oauth2Client.verifyIdToken({
      idToken: tokens.id_token,
      audience: config.google.clientID,
    })
  ).payload;

  if (!UserIndex.email[userInfo.email]) {
    const newUser = {
      name: userInfo.name,
      email: userInfo.email,
      o_id: userInfo.sub,
      picture: userInfo.picture,
      r_token: tokens.refresh_token,
    };
...

Besides decoding the JWT, we check if we have the current email in our database, and if not, we create a new record.

More information from Google:

https://developers.google.com/identity/oauth2/web/guides/how-user-authz-works

https://developers.google.com/identity/protocols/oauth2/openid-connect

https://developers.google.com/identity/oauth2/web/guides/use-token-model

While doing testing, you’ll might need to sometimes remove granted access to your app, you can do that here:

https://myaccount.google.com/permissions

Leave a Reply