How to implement Google Sign In with Express.js

Updated: December 30, 2023 By: Guest Contributor Post a comment

Introduction

Implementing Google Sign-In in your Express.js application allows users to register or log in with their Google accounts, enhancing user experience by providing a familiar authentication method. This article explores the integration process using the latest Node.js and JavaScript/TypeScript features such as arrow functions, async/await, and ES modules. We’ll assume you’re familiar with Node.js & Express and have a basic understanding of OAuth 2.0.

Setting Up the Project

Before implementing Google Sign-In, we need to set up an Express.js project and install required packages. Create your project directory and initialize a new node project:

mkdir my-google-sign-in
 cd my-google-sign-in
 npm init -y

Next, install Express and other dependencies:

npm install express passport passport-google-oauth20 dotenv

Configuring Google API Credentials

To use Google Sign-In, you need to create a project in Google Cloud Platform, enable the Google+ API and create credentials:

  • Go to the Google Developers Console.
  • Create a new project or select an existing one.
  • Navigate to “OAuth Consent Screen” tab and set up the consent screen details.
  • Go to the “Credentials” tab and click “Create credentials” > “OAuth client ID”.
  • Choose “Web application” and set the authorized redirect URIs (e.g., http://localhost:3000/auth/google/callback).
  • Upon creating your credentials, you’ll receive your client ID and client secret which are to be kept secure.

Implementing Google Sign-In Backend

Inside your Express application, create or edit an environment file to store your Google API credentials:

//.env
GOOGLE_CLIENT_ID=your_client_id
GOOGLE_CLIENT_SECRET=your_client_secret

Using the passport.js library, setup the Google authentication strategy:

//auth.js
import passport from 'passport';
import { Strategy as GoogleStrategy } from 'passport-google-oauth20';
import dotenv from 'dotenv';
dotenv.config();

passport.use(new GoogleStrategy({
    clientID: process.env.GOOGLE_CLIENT_ID,
    clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    callbackURL: "/auth/google/callback"
  },
  async (accessToken, refreshToken, profile, cb) => {
    // Here you would find or create a user in your database
    cb(null, profile);
  })
);

Once the authentication strategy is in place, create the Express routes to handle authentication requests:

//index.js
import express from 'express';
import passport from './auth.js';

const app = express();
app.use(passport.initialize());

app.get('/auth/google',
  passport.authenticate('google', { scope: ['profile'] })
);

app.get('/auth/google/callback', 
  passport.authenticate('google', { failureRedirect: '/login' }),
  (req, res) => {
    // Successful authentication, redirect home.
    res.redirect('/');
  }
);

app.listen(3000, () => {
  console.log('Server started on http://localhost:3000');
});

Complete Example

Here’s a simplified, complete code example:

// Import necessary modules
import express from 'express';
import passport from 'passport';
import { Strategy as GoogleStrategy } from 'passport-google-oauth20';
import dotenv from 'dotenv';

// Load environment variables
dotenv.config();

// Google OAuth2 Strategy Configuration
passport.use(new GoogleStrategy({
    clientID: process.env.GOOGLE_CLIENT_ID,
    clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    callbackURL: "/auth/google/callback"
  },
  async (accessToken, refreshToken, profile, cb) => {
    // In a real application, you would find or create a user in your database here
    cb(null, profile);
  })
);

// Initialize Express application
const app = express();

// Initialize Passport
app.use(passport.initialize());

// Define routes
app.get('/auth/google',
  passport.authenticate('google', { scope: ['profile'] })
);

app.get('/auth/google/callback', 
  passport.authenticate('google', { failureRedirect: '/login' }),
  (req, res) => {
    // Successful authentication, redirect home
    res.redirect('/');
  }
);

// Start the server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server started on http://localhost:${PORT}`);
});

Before running this code, ensure you have a .env file in the root of your project with your Google Client ID and Client Secret:

GOOGLE_CLIENT_ID=your_client_id
GOOGLE_CLIENT_SECRET=your_client_secret

This code sets up an Express server that utilizes the Passport.js library with the Google OAuth2 strategy for authentication. It defines routes for initiating the Google authentication process and handling the callback after Google authenticates the user. Upon successful authentication, the user is redirected to the home route.

This example provides the basic structure for integrating Google Sign-In and should be expanded with proper user handling and security measures for a production application.

Conclusion

Incorporating Google Sign-In in an Express.js application streamlines user authentication, leveraging Google’s security and providing a quick sign-in experience. With this simple guide and the power of OAuth 2.0 and Passport.js, you can conveniently integrate third-party authorization mechanisms into your projects.