OAuth 2.0 Authentication and Authorization - sonuprajapati15/Authentication-Authorization GitHub Wiki

System Design: OAuth 2.0 Authentication and Authorization

1. Overview

OAuth 2.0 is an authorization framework that enables third-party applications to access user data from another service without exposing user credentials. It is widely used for authentication in APIs, Single Sign-On (SSO), and third-party integrations.

🔹 Example: Logging into a website using Google, Facebook, or GitHub credentials.


2. Functional & Non-Functional Requirements

Functional Requirements

✅ Users can log in using an OAuth provider (Google, GitHub, etc.).
✅ The system must support multiple OAuth providers.
✅ Access tokens are issued and validated before granting access.
✅ Tokens have expiration times and can be refreshed.
✅ Users can revoke permissions at any time.

Non-Functional Requirements

Security – Use HTTPS, PKCE (for public clients), secure token storage.
Scalability – Handle multiple OAuth providers with token validation.
Performance – Optimize token verification with caching.
Compliance – Follow GDPR and data privacy laws.
User Experience – Seamless authentication flow with minimal user friction.


3. High-Level Design (HLD)

Architecture Components

  1. Client (Web/Mobile App) – Initiates authentication with an OAuth provider.
  2. OAuth Provider (Google, GitHub, etc.) – Authenticates users and issues tokens.
  3. Authorization Server – Manages OAuth flows, stores tokens, and handles access control.
  4. Resource Server (API, Backend Service) – Verifies access tokens before granting access.

OAuth 2.0 Workflow

  1. User Initiates Login – Redirects to the OAuth provider (e.g., Google).
  2. User Grants Permission – OAuth provider asks the user to authorize access.
  3. Authorization Code Exchange – The client receives an authorization code.
  4. Access Token Request – The client exchanges the code for an access token.
  5. Access Protected Resources – The access token is used to access APIs.
  6. Token Expiry & Refresh – Refresh tokens can be used to get new access tokens.
  7. Logout & Revocation – Users can revoke access at any time.

4. Low-Level Design (LLD)

Database Schema

CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    oauth_provider VARCHAR(50) NOT NULL,
    oauth_id VARCHAR(255) UNIQUE NOT NULL,
    email VARCHAR(255) UNIQUE NOT NULL,
    name VARCHAR(255),
    profile_picture TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE oauth_tokens ( id SERIAL PRIMARY KEY, user_id INT REFERENCES users(id) ON DELETE CASCADE, access_token TEXT NOT NULL, refresh_token TEXT, expires_at TIMESTAMP NOT NULL );

API Endpoints

Method Endpoint Description
GET /auth/google Redirects to Google OAuth login
GET /auth/callback Handles OAuth provider response
GET /profile Fetches user profile (protected route)
POST /logout Revokes access token and logs out

6. Diagrams

Flowchart – OAuth 2.0 Authentication Workflow

Here is the OAuth 2.0 Authentication Flowchart:

OAuth 2.0 Authentication Flow

View or edit this diagram in Whimsical.


7. Code Implementation (Node.js + Express + Passport.js + Google OAuth)

1. Install Dependencies

npm install express passport passport-google-oauth20 express-session dotenv

2. Setup Express Server with Google OAuth

require("dotenv").config();
const express = require("express");
const passport = require("passport");
const session = require("express-session");
const GoogleStrategy = require("passport-google-oauth20").Strategy;

const app = express();

// Session setup app.use(session({ secret: "mysecret", resave: false, saveUninitialized: true }));

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

// Configure Google OAuth passport.use( new GoogleStrategy( { clientID: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, callbackURL: "/auth/callback", }, (accessToken, refreshToken, profile, done) => { return done(null, profile); } ) );

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

// OAuth Routes app.get("/auth/google", passport.authenticate("google", { scope: ["profile", "email"] })); app.get("/auth/callback", passport.authenticate("google", { failureRedirect: "/" }), (req, res) => { res.redirect("/profile"); });

app.get("/profile", (req, res) => { if (!req.isAuthenticated()) return res.status(401).json({ message: "Unauthorized" }); res.json({ user: req.user }); });

app.post("/logout", (req, res) => { req.logout(() => res.json({ message: "Logged out" })); });

app.listen(3000, () => console.log("Server running on port 3000"));


Token Storage Options

  • Access tokens – Stored in memory, Redis, or HTTP-only cookies.
  • Refresh tokens – Stored securely in the database.

OAuth 2.0 Grant Types

  1. Authorization Code Flow (recommended for web apps).
  2. Implicit Flow (deprecated due to security issues).
  3. Client Credentials Flow (for machine-to-machine authentication).
  4. Password Grant (not recommended, only for first-party clients).

5. Trade-offs & Scalability

Factor Trade-off
Scalability OAuth is scalable but requires efficient token storage.
Security PKCE, HTTPS, and refresh tokens mitigate attacks.
Performance Caching tokens improves API response times.
Compliance OAuth helps with GDPR compliance, but requires proper user consent tracking.

8. Conclusion

OAuth 2.0 is the gold standard for secure authentication in modern web applications. It enables seamless third-party logins, enhances security, and improves user experience while providing fine-grained control over permissions.

⚠️ **GitHub.com Fallback** ⚠️