How to Add Google OAuth2 Login in Node.js

Telegram Group Join Now
WhatsApp Group Join Now

Want to provide a seamless login experience for your users? Of course, you do! Integrating Google OAuth2 login into your Node.js application is a fantastic way to boost security and user convenience. And guess what? I’m here to tell you it’s surprisingly simple with Passport.js, the go-to authentication middleware for Node.js. In this comprehensive guide, we’ll walk through setting up Google OAuth2 authentication in your Node.js app using Passport.js – no prior experience needed.

Let’s get started.

Setting up Your Google Cloud Platform Project

Before we dive into code, we need to lay the groundwork for our Google OAuth2 implementation. This involves setting up a project on the Google Cloud Platform (GCP), which acts as the control center for our authentication process. Think of it as creating the VIP guest list for your app, where Google handles the invitations and ensures only authorized users get through the door.

Here’s how:

1. Navigate to the Google Cloud Platform Console

Open your web browser and head over to the Google Cloud Platform Console. If you don’t have a Google account, you’ll need to create one before proceeding.

2. Create a New Project

Once you’re on the GCP console, you’ll be greeted with a project selection screen. Since we’re starting fresh, click on the “Create Project” button. You’ll be asked to provide a project name – choose something descriptive and relevant to your application.

3. Enable the “Google+ API”

Now, here’s where things might seem a bit counterintuitive. Even though we’re setting up Google OAuth2, we need to enable the “Google+ API.” I know, I know, it sounds strange. But trust me, it’s a necessary step.

To enable the API:

  • From the GCP console, go to the “APIs & Services” section.
  • Click on “Library.”
  • Search for “Google+ API” and select it.
  • Click on the “Enable” button.

4. Create OAuth 2.0 Client IDs Credentials

With the API enabled, we can now create the credentials that will allow our Node.js app to communicate securely with Google’s authentication servers.

  • In the GCP console, navigate to the “Credentials” section under “APIs & Services.”
  • Click on “Create Credentials” and select “OAuth client ID.”
  • You’ll be prompted to choose an application type. Select “Web application” from the list.

5. Configure the Authorized Redirect URI

This is where the magic happens! The authorized redirect URI acts as the digital bouncer, telling Google where to send users after they’ve successfully authenticated.

  • In the “Authorized redirect URIs” field, enter the URL that Google should redirect users to after authentication. This URL should point to a specific route in your Node.js application that will handle the authentication response.

    Example: http://localhost:3000/auth/google/callback (This assumes your Node.js app is running locally on port 3000)

  • Click “Create” to generate your client ID and client secret. Keep these safe, as we’ll need them to configure Passport.js in our Node.js app.

OAuth2

Installing the Required Dependencies

Now, let’s shift gears and start setting up our Node.js environment. Our weapons of choice? The mighty Passport.js and its trusty sidekick, the Passport Google OAuth2 strategy. Think of these libraries as the authentication dream team, simplifying the often-complex world of OAuth2 into a few lines of elegant code.

Here’s the game plan:

  1. Open Your Terminal: Fire up your trusty terminal or command prompt.
  2. Navigate to Your Project Directory: Use the cd command to navigate to the root directory of your Node.js project.

    Example: cd my-awesome-nodejs-app

  3. Install with npm: Use the following command to install Passport.js and the Passport Google OAuth2 strategy:
    npm install passport passport-google-oauth20 --save
    

That’s it! You’ve successfully recruited the authentication A-team to your project. Now, let’s get them into formation!

Configuring Passport.js for Google OAuth2

With our dependencies installed, it’s time to configure Passport.js and teach it how to tango with Google OAuth2. This involves initializing the Passport Google OAuth2 strategy, providing it with the credentials we generated earlier, and setting up session management to keep track of our authenticated users.

Let’s break it down:

  1. Create a Passport Configuration File: Create a new file (e.g., passport.js) within your Node.js project. This is where we’ll define our Passport.js configuration.
  2. Require the Necessary Modules: Start by requiring the necessary modules: passport and passport-google-oauth20.
    const passport = require('passport');
    const GoogleStrategy = require('passport-google-oauth20').Strategy;
    
  3. Initialize the Google OAuth2 Strategy:
    passport.use(
      new GoogleStrategy(
        {
          clientID: 'YOUR_CLIENT_ID', // Replace with your actual client ID
          clientSecret: 'YOUR_CLIENT_SECRET', // Replace with your actual client secret
          callbackURL: 'http://localhost:3000/auth/google/callback', // Your callback URL
        },
        (accessToken, refreshToken, profile, done) => {
          // This callback function will be called after successful authentication
          // Here, you can access the user's profile information from 'profile'
          // You can save the user to your database, create a session, etc.
          console.log('User profile:', profile);
    
          // For now, we'll just call 'done' to proceed
          return done(null, profile); 
        }
      )
    );
    

    Let’s break down this configuration:

    • clientID and clientSecret: Replace the placeholders with the client ID and client secret you obtained from the Google Cloud Platform.
    • callbackURL: Ensure this matches the authorized redirect URI you configured in your Google Cloud Platform project.
    • Callback Function: This function is executed after successful authentication with Google.
      • accessToken: A short-lived token that allows your app to access user data on behalf of the user.
      • refreshToken: A longer-lived token that can be used to obtain a new access token.
      • profile: An object containing the user’s profile information (e.g., name, email, profile picture).
      • done: A callback function that you must call to signal the completion of the authentication process.
  4. Implement Session Management (Optional):

    If you need to maintain user sessions (which you likely will), you’ll need to implement session management using libraries like express-session. We won’t delve into the specifics here, but you can find excellent resources on how to implement session management in Node.js.

  5. Serialize and Deserialize User Data (Important for Sessions):
    passport.serializeUser((user, done) => {
      // This function serializes the user object for storing in the session
      // Typically, you would extract a unique identifier (e.g., user ID) 
      // and store it in the session.
      done(null, user.id); 
    });
    
    passport.deserializeUser((id, done) => {
      // This function retrieves the user object from the session
      // based on the serialized identifier (e.g., user ID)
      User.findById(id, (err, user) => { // Assuming you have a 'User' model
        done(err, user);
      });
    });
    
    • serializeUser: Called when a user is successfully authenticated. Typically, you’d extract a unique identifier (like a user ID) and store it in the session.
    • deserializeUser: Called on subsequent requests to retrieve the full user object from the session based on the stored identifier.

Creating the Authentication Routes

With Passport.js configured, let’s set up the routes in our Node.js app to handle the Google OAuth2 authentication flow.

We’ll need two routes:

  1. /auth/google: This route will initiate the authentication process, redirecting the user to Google’s login page.
  2. /auth/google/callback: This route will handle the callback from Google after the user has authenticated.

Here’s how you can define these routes in an Express.js app:

const express = require('express');
const router = express.Router();
const passport = require('passport'); // Make sure you've required Passport.js

// Route to initiate Google OAuth2 authentication
router.get(
  '/auth/google',
  passport.authenticate('google', {
    scope: ['profile', 'email'] // Request access to user profile and email
  })
);

// Callback route after successful authentication
router.get(
  '/auth/google/callback',
  passport.authenticate('google', { failureRedirect: '/login' }), // Redirect on failure
  (req, res) => {
    // Successful authentication!
    // Redirect the user to a protected page or home page
    res.redirect('/dashboard'); // Example: Redirect to user dashboard
  }
);

module.exports = router;
  • passport.authenticate('google', { scope: ['profile', 'email'] }):
    • passport.authenticate('google') initiates the Google OAuth2 flow using the strategy we defined earlier.
    • The { scope: ['profile', 'email'] } option specifies the permissions we want to request from the user. In this case, we’re requesting access to their profile information and email address.
  • passport.authenticate('google', { failureRedirect: '/login' }):
    • This handles the callback from Google.
    • The failureRedirect option specifies where to redirect the user if authentication fails (e.g., if they deny access or if there’s an error).

Handling the Authentication Callback

In the callback route (/auth/google/callback), we’ve already set up Passport.js to handle the heavy lifting of verifying the authentication response from Google. Our primary responsibility here is to redirect the user to the appropriate destination based on the success or failure of the authentication.

Here’s a closer look at the callback route code:

router.get(
  '/auth/google/callback',
  passport.authenticate('google', { failureRedirect: '/login' }), // Redirect on failure
  (req, res) => {
    // Successful authentication!
    // Redirect the user to a protected page or home page
    res.redirect('/dashboard'); 
  }
);
  1. passport.authenticate('google', { failureRedirect: '/login' }): This middleware function from Passport.js does the following:
    • Receives the authentication response from Google.
    • Verifies the authenticity of the response.
    • If successful, calls the callback function we defined in our Passport.js configuration.
    • If unsuccessful (e.g., user denies access, error occurs), redirects the user to the specified failureRedirect URL (in this case, /login).
  2. Success Callback: If authentication is successful, the code within the second callback function ((req, res) => { ... }) will be executed.
    • res.redirect('/dashboard'): This redirects the user to a protected route (e.g., /dashboard) or a home page, indicating that they have successfully logged in. You can customize this redirect URL based on your application’s needs.

Protecting Routes and Accessing User Information

Now that we have our authentication flow in place, let’s explore how to protect sensitive routes in our application and access valuable user information provided by Google OAuth2. This allows us to create personalized experiences and restrict access to authorized users.

1. Protecting Routes

Passport.js makes it incredibly simple to protect routes, ensuring that only authenticated users can access them. Here’s how:

const express = require('express');
const router = express.Router();
const passport = require('passport');

// Protect a route using the 'ensureAuthenticated' middleware
router.get('/dashboard', ensureAuthenticated, (req, res) => {
  // This route is now protected! Only authenticated users can access it.
  // You can access user information from 'req.user' 
  res.render('dashboard', { user: req.user }); // Example: Rendering a dashboard template
});

// Middleware function to check for authentication
function ensureAuthenticated(req, res, next) {
  if (req.isAuthenticated()) {
    // User is authenticated, proceed to the next middleware or route handler
    return next(); 
  } else {
    // User is not authenticated, redirect to the login page
    res.redirect('/login'); 
  }
}

Explanation:

  • ensureAuthenticated Middleware: This custom middleware function checks if the user is authenticated using req.isAuthenticated(), provided by Passport.js.
    • If authenticated: The user is allowed to proceed to the protected route.
    • If not authenticated: The user is redirected to the login page (/login in this case).
  • router.get('/dashboard', ensureAuthenticated, (req, res) => { ... });: We apply the ensureAuthenticated middleware to our protected route (/dashboard) to enforce authentication.

2. Accessing User Information

Once a user is authenticated, you can access their profile information from the req.user object within any protected route. This object contains the user’s profile as provided by Google.

router.get('/dashboard', ensureAuthenticated, (req, res) => {
  const user = req.user;
  // Now you can access user properties:
  // user.id, user.displayName, user.emails[0].value (for the email), etc.
  res.send(`Hello, ${user.displayName}! Your email is ${user.emails[0].value}`);
});

Remember:

  • Replace placeholder values (client ID, client secret, callback URLs) with your actual values.
  • Customize redirect URLs and error handling according to your application’s specific requirements.
  • Thoroughly test your implementation to ensure a smooth and secure authentication experience for your users.

Implementing Google OAuth2 login might seem daunting at first, but with Passport.js at your disposal, it becomes a surprisingly manageable and rewarding task. By following this comprehensive guide, you’ve taken significant steps towards enhancing the security and usability of your Node.js application. Keep experimenting, keep learning, and keep building amazing things.

Read Also:

How to Install MongoDB 8 on Ubuntu 24.04 LTS Linux

Power BI: Guide to Data Visualization & Analytics

Leave a comment