how-to-implement-oauth-20-in-a-nodejs-api-with-expressjs.html

How to Implement OAuth 2.0 in a Node.js API with Express.js

In today’s digital landscape, securing web applications is more important than ever. One of the most widely adopted methods for authentication and authorization is OAuth 2.0. In this article, we will explore how to implement OAuth 2.0 in a Node.js API using the Express.js framework.

What is OAuth 2.0?

OAuth 2.0 is an authorization framework that allows third-party applications to gain limited access to user accounts on an HTTP service. It enables users to grant access to their information without sharing their passwords. This is particularly useful for applications that require access to user data from services like Google, Facebook, or GitHub.

Use Cases for OAuth 2.0

  • Social Logins: Allow users to log in using their existing accounts on social media platforms.
  • Third-party Integrations: Enable applications to access user data from external services without compromising user credentials.
  • Mobile Applications: Securely authenticate users in mobile apps while minimizing the risk of exposing sensitive information.

Setting Up the Node.js Environment

Before we dive into the implementation, let’s set up our Node.js environment.

Step 1: Initialize Your Project

Open your terminal and create a new directory for your project:

mkdir oauth2-example
cd oauth2-example
npm init -y

Step 2: Install Required Packages

You will need several packages to implement OAuth 2.0, including express, axios, dotenv, and express-session:

npm install express axios dotenv express-session passport passport-google-oauth20
  • express: A minimal and flexible Node.js web application framework.
  • axios: A promise-based HTTP client for making requests.
  • dotenv: For managing environment variables.
  • express-session: To manage user sessions.
  • passport: A middleware for authentication.
  • passport-google-oauth20: A Passport strategy for Google OAuth 2.0.

Step 3: Create Your Project Structure

Create the following files and folders:

oauth2-example/
│
├── .env
├── app.js
└── routes/
    └── auth.js

Implementing OAuth 2.0

Step 1: Configure Environment Variables

Open the .env file and add your Google client ID and secret. You can create credentials in the Google Developer Console.

GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
SESSION_SECRET=your_session_secret

Step 2: Set Up Express Server

Open the app.js file and set up your Express server along with Passport for authentication.

const express = require('express');
const session = require('express-session');
const passport = require('passport');
const dotenv = require('dotenv');
const authRoutes = require('./routes/auth');

dotenv.config();

const app = express();

// Middleware
app.use(express.json());
app.use(session({
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: true,
}));
app.use(passport.initialize());
app.use(passport.session());

// Routes
app.use('/auth', authRoutes);

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

Step 3: Configure Passport for Google OAuth

In the routes/auth.js file, configure Passport to use Google OAuth 2.0.

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

const router = express.Router();

passport.use(new GoogleStrategy({
    clientID: process.env.GOOGLE_CLIENT_ID,
    clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    callbackURL: '/auth/google/callback'
  },
  (accessToken, refreshToken, profile, done) => {
    // You can save user info to the database here if needed
    return done(null, profile);
  }
));

// Serialize user
passport.serializeUser((user, done) => {
  done(null, user);
});

// Deserialize user
passport.deserializeUser((user, done) => {
  done(null, user);
});

// Auth Routes
router.get('/google', passport.authenticate('google', { scope: ['profile', 'email'] }));

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

router.get('/logout', (req, res) => {
  req.logout(err => {
    if (err) { return next(err); }
    res.redirect('/');
  });
});

module.exports = router;

Step 4: Adding a Basic Frontend

While this guide focuses on the backend, you can create a simple HTML file in your project root to test your API.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>OAuth 2.0 Example</title>
</head>
<body>
    <h1>OAuth 2.0 Example</h1>
    <a href="/auth/google">Login with Google</a>
</body>
</html>

Step 5: Testing Your Implementation

  1. Run your server: bash node app.js

  2. Open your browser and navigate to http://localhost:3000. Click on "Login with Google" to test your OAuth 2.0 implementation.

Troubleshooting Tips

  • Invalid Credentials: Ensure that your Google credentials are correctly set in the .env file.
  • Callback URL Issues: Make sure the callback URL in your Google Developer Console matches the one in your GoogleStrategy.
  • Session Issues: If sessions are not working, check that your session secret is set and that you are using express-session properly.

Conclusion

Implementing OAuth 2.0 in a Node.js API with Express.js enhances the security of your application while providing a seamless user experience. By following the steps outlined in this article, you can successfully integrate authentication into your web applications. As you continue to develop, consider exploring additional features like token expiration and refresh tokens for a more robust implementation. Happy coding!

SR
Syed
Rizwan

About the Author

Syed Rizwan is a Machine Learning Engineer with 5 years of experience in AI, IoT, and Industrial Automation.