Seamless Google OAuth 2.0 Auth with Node.js & Passport.js

Seamless Google OAuth 2.0 Auth with Node.js & Passport.js

Introduction

OAuth 2.0 has become one of the most popular authentication mechanisms for web and mobile applications. It allows apps to securely delegate authentication to external identity providers like Google, Facebook, Twitter etc. This saves the effort of building custom login, registration and account management features.

In this post, we will walk through implementing OAuth 2.0 login with Google in a Node.js app using Passport.js middleware.

OAuth 2.0 Basics

OAuth is an authorization framework that enables apps to access resources hosted by a service provider on behalf of users, without exposing their credentials. It establishes trust through token-based interactions involving the user, client app and service provider.

The core OAuth 2.0 roles are:

  • Resource Owner – The user who authorizes access to their account data.
  • Client – The app requesting access to user data based on their authorization.
  • Resource Server – API server hosting protected user data and resources.
  • Authorization Server – Server generating access tokens after user authorization.

The typical OAuth flow has three main steps:

  1. The client app redirects the user to the OAuth provider to authenticate and authorize access.
  2. The OAuth provider authenticates the user, obtains their authorization, and redirects back with an authorization code.
  3. The client app uses the authorization code to obtain an access token from the OAuth server. This token can be used to access the user’s data from the resource server.

Setting up the Node.js App

Let’s start by initializing a simple Node.js app with Express:

$ npm init
$ npm install express

Now we can implement a basic Express server with some routes:

// index.js

const express = require('express');

const app = express();

app.get('/', (req, res) => {
  res.send('Homepage');
});

app.get('/profile', (req, res) => {
  res.send('Profile page');
});

app.listen(3000);

This will serve a basic homepage and profile page on port 3000.

Integrating Passport.js

Passport is a popular Node.js middleware for handling authentication. It supports common strategies like OAuth, OpenID and more out of the box and can be extended further.

Let’s add Passport along with the Passport OAuth strategy:

$ npm install passport passport-google-oauth20

We first need to configure Passport to use the GoogleStrategy and provide our OAuth credentials:

// config/passport.js

const GoogleStrategy = require('passport-google-oauth20').Strategy;

const GOOGLE_CLIENT_ID = '<CLIENT_ID>';
const GOOGLE_CLIENT_SECRET = '<CLIENT_SECRET>';

passport.use(new GoogleStrategy({
  clientID: GOOGLE_CLIENT_ID,
  clientSecret: GOOGLE_CLIENT_SECRET,
  callbackURL: "/auth/google/callback"
},
function(accessToken, refreshToken, profile, done) {
   // user authenticated 
}));

The callback function will be invoked after Google authentication completes.

To enable Passport middleware in the Express app:

// index.js

const passport = require('passport');
require('./config/passport');

app.use(passport.initialize());
app.use(passport.session());

Implementing Login and Logout

The passport.authenticate method initiates the Google OAuth flow. We can trigger Google login on a route:

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

This will redirect the user to Google where they will authenticate and authorize our app.

Once authorized, Google redirects back to the callback route we specified in Passport config:

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

Here Passport automatically handles the token exchange using the authorization code and retrieves the user’s profile.

To log the user out, we just call req.logout():

app.get('/logout', (req, res) => {
  req.logout();
  res.redirect('/');
});

That covers the login and logout flow with Passport.js!

Accessing User Data

Once login is successful, Passport will establish a persistent login session and serialize the user data to req.user.

We can access the user’s Google profile data on protected routes like:

app.get('/profile', (req, res) => {
  res.send(req.user); //get user data
});

This keeps the user authenticated across requests until they logout.

Frequently Asked Questions

What is OAuth 2.0 used for?

OAuth allows apps to securely authenticate using external providers like Google, Facebook etc instead of implementing custom login.

What are the main advantages of using Passport.js?

Passport provides an easy way to integrate various authentication strategies in Node.js via middleware with minimal code.

What should we do once the user is authenticated?

The user profile data is available in req.user on protected routes. We can use it to customize experience, save to database etc.

How do we call Google APIs on behalf of the user?

The access token received during login flow can be used to make authorized API calls to Google services.

What additional security measures should be taken?

CSRF protection, input validation, encryption, rate limiting etc should be added for production apps.

Conclusion

In this article, we implemented OAuth 2.0 authentication with Google using Passport.js in a Node.js app. The key steps were:

  • Configuring Passport with OAuth credentials
  • Adding Passport middleware to Express
  • Initiating login flow using passport.authenticate
  • Handling authorization callback to obtain user profile
  • Accessing serialized user data from req.user
  • Logging user out by clearing session

This allows implementing a secure login flow while offloading authentication logic to Google OAuth. Passport makes the integration seamless with its middleware-based approach. For production use, additional steps like error handling, databases, CSRF protection etc should be added.

Hope you enjoyed this hands-on introduction to Passport.js and OAuth in Node.js!

One thought on “Seamless Google OAuth 2.0 Auth with Node.js & Passport.js”

Leave a Reply

Your email address will not be published. Required fields are marked *