API with NestJS #42. Authenticating users with Google

JavaScript NestJS TypeScript

This entry is part 42 of 48 in the API with NestJS

Authenticating users with emails and passwords is a valid and common approach. However, a convenient alternative is to shift this responsibility to a third party. In this article, we look into adding Google authentication to a NestJS project.

We can achieve the above because Google uses the OAuth (Open Authorization) framework. With it, Google users can grant access to some of their data to an application – in this case, us. In this series, we’ve already implemented a way to register users. Therefore, this article aims to implement an additional way of registering users with Google that can work besides authenticating with a password and an email. Because of that, in this article, we won’t be using the popular passport-google-oauth20 library.

Registering an application

The first step in implementing authentication with Google is registering an application in the Google Cloud Platform dashboard.

When we have a project, we need to set up the OAuth consent screen.

When configuring it, we need to set up some basic information about our application. For example, if we would like to deploy our application and use it outside of localhost, we would need to register our domain.

For testing purposes, we also need to specify a list of users that are allowed to use our application. If we would like our application to be available to any user, we need to submit our app for verification.

After sorting out the above, we need to generate OAuth Client ID credentials for our application in the credentials dashboard.

We could also set the redirect URL, but in this article we use a different approach that doesn’t use it.

Above, in the authorized JavaScript origins, we put the URL of our frontend application. We also need to specify the redirect URL. Google will redirect the user to it after successful authentication.

Finalizing the process of creating the credentials gives us the client ID and the client secret. We need to save them in the environment variables.

app.module.ts

.env

The frontend side

To implement authentication with Google in our application, we need to allow the users to type in their Google credentials. A straightforward way to do that in React is to use the react-google-login library.

In this simple example we use Create React App.

First, we need to add some environment variables.

.env

react-app-env.d.ts

Once we have the above, we can use the react-google-login library.

GoogleButton.tsx

Clicking on the above button causes a popup to show.

To change the above behavior, we could pass to the component. This would cause a full redirect instead of opening a popup.

When the user successfully authenticates, the callback is invoked.

useGoogleAuthentication.tsx

Above, we take the from the response and send it to our NestJS API.

Implementing Google authentication with NestJS

The last step in authenticating our users is receiving the from Google and logging the user into our system.

googleAuthentication.controller.ts

Above, we expect the frontend to call the endpoint with the access token.

tokenVerificationDto.ts

The final part of the implementation is the method.

googleAuthentication.service.ts

Registering new users

The crucial part is that the users can be signed up into our system at this point, but they don’t have to be. Therefore, we need to handle both cases. Let’s start with registering the user.

googleAuthentication.service.ts

In our API, we require the user to provide a name. We can get this data from the Google API. Unfortunately, the googleapis library requires us to do that in a way that is a bit odd.

googleAuthentication.service.ts

When the users are not registered yet, we add them to our database with the method.

googleAuthentication.service.ts

Above, you can see that we add the user to Stripe. If you want to know more, check out API with NestJS #36. Introduction to Stripe with React

To handle it properly, let’s make some changes to the :

user.entity.ts

Please notice that the password is now nullable, because we don’t need it for users authenticated with Google. It would be a good idea to modify the existing code usef for verifying the user’s password to account for this change.

Returning the data of the user

When the users are registered, we need to generate cookies for them.

If you want to know more about this approach, check out API with NestJS #3. Authenticating users with bcrypt, Passport, JWT, and cookies

googleAuthentication.service.ts

Above you can see that we generate refresh tokens. To read more about it, check out API with NestJS #13. Implementing refresh tokens using JWT

Thanks to implementing all of the above, the handles both new and returning users.

To see the whole picture more accurately, check out the full code for the .

Summary

In this article, we’ve implemented a way for our users to authenticate with Google. Moreover, we’ve done it in a way that integrates with our existing system. To do that, we register users into our own database instead of relying upon Google. Thanks to doing so, we don’t have to make significant changes to the existing code that takes care of registering users with the email and the password.

Series Navigation<< API with NestJS #41. Verifying phone numbers and sending SMS messages with TwilioAPI with NestJS #43. Introduction to MongoDB >>
Subscribe
Notify of
guest
1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Nathanael Cunningham
Nathanael Cunningham
1 month ago

What is the workflow for checking if the user is authenticated from a request on the frontend after the user logs in?