Types of Authentication Methods - Comparing Sessions, Tokens, and OAuth

16 min read | 2025.12.08

The Difference Between Authentication and Authorization

First, let’s clarify two concepts that are often confused.

  • Authentication: “Who are you?” - Verifying a user’s identity
  • Authorization: “What can you do?” - Verifying access permissions
flowchart LR
    Login["Login"] -->|Authentication| Auth["Verify identity with ID/Password"]
    Auth --> Action["Action"]
    Action -->|Authorization| Perm["Check if user has permission for this action"]

Comparison of Authentication Methods

MethodState ManagementSuitable Cases
Session AuthenticationServer-sideTraditional web apps
Token Authentication (JWT)Client-sideSPA, mobile apps
OAuth 2.0External serviceThird-party auth, API integration

Session Authentication

How It Works

sequenceDiagram
    participant Client
    participant Server

    Note over Client, Server: 1. Login
    Client->>Server: Send ID/Password
    Server->>Server: Authenticate → Generate Session ID → Store in session store
    Server->>Client: Set-Cookie: session_id=abc123

    Note over Client, Server: 2. Subsequent Requests
    Client->>Server: Cookie: session_id=abc123
    Server->>Server: Validate Session ID in session store

Implementation Example

// Express.js + express-session
const session = require('express-session');
const RedisStore = require('connect-redis').default;

app.use(session({
  store: new RedisStore({ client: redisClient }),
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: false,
  cookie: {
    secure: true,      // HTTPS required
    httpOnly: true,    // No JS access
    sameSite: 'strict', // CSRF protection
    maxAge: 24 * 60 * 60 * 1000 // 24 hours
  }
}));

// Login
app.post('/login', async (req, res) => {
  const user = await authenticate(req.body);
  if (user) {
    req.session.userId = user.id;
    res.json({ success: true });
  }
});

Pros and Cons

ProsCons
Easy to invalidate sessionsRequires server-side state management
Easy security controlNeed session sharing in distributed environments
Simple implementationPoor compatibility with mobile apps

Token Authentication (JWT)

How It Works

sequenceDiagram
    participant Client
    participant Server

    Note over Client, Server: 1. Login
    Client->>Server: Send ID/Password
    Server->>Server: Authenticate → Generate JWT (with signature)
    Server->>Client: { "token": "eyJhbG..." }

    Note over Client, Server: 2. Subsequent Requests
    Client->>Server: Authorization: Bearer eyJhbG...
    Server->>Server: Validate JWT signature (no store access needed)

JWT Structure

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.     ← Header
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6...   ← Payload
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c ← Signature

Header (Base64 decoded):
{ "alg": "HS256", "typ": "JWT" }

Payload (Base64 decoded):
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022,
  "exp": 1516325422
}

Implementation Example

const jwt = require('jsonwebtoken');

// Token generation
app.post('/login', async (req, res) => {
  const user = await authenticate(req.body);
  if (user) {
    const token = jwt.sign(
      { userId: user.id, role: user.role },
      process.env.JWT_SECRET,
      { expiresIn: '1h' }
    );
    res.json({ token });
  }
});

// Token verification middleware
function authMiddleware(req, res, next) {
  const token = req.headers.authorization?.split(' ')[1];
  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded;
    next();
  } catch (error) {
    res.status(401).json({ error: 'Invalid token' });
  }
}

Refresh Tokens

Token TypeLifespanStorage
Access TokenShort-lived (15 min - 1 hour)Memory/localStorage
Refresh TokenLong-lived (7 - 30 days)Stored securely

Flow:

  1. Access Token expires
  2. Get new Access Token using Refresh Token
  3. Refresh Token also expires → Re-login required

Pros and Cons

ProsCons
Stateless, easy to scaleDifficult to invalidate tokens
Suitable for distributed systemsLarge token size
Suitable for mobile/SPAPayload is not encrypted

OAuth 2.0

Overview

A mechanism for authentication and authorization using third-party services (Google, GitHub, etc.).

sequenceDiagram
    participant User
    participant App as Your App (Client)
    participant Auth as Auth Server (Google, etc.)

    User->>App: 1. Click Login Button
    App->>Auth: 2. Auth Request
    Auth->>User: 3. Login Screen
    User->>Auth: 4. Authenticate & Consent
    Auth->>App: 5. Auth Code
    App->>Auth: 6. Token Request
    Auth->>App: 7. Access Token
    App->>User: 8. Login Complete

Implementation Example (Authorization Code Flow)

// 1. Authorization request
app.get('/auth/google', (req, res) => {
  const authUrl = new URL('https://accounts.google.com/o/oauth2/v2/auth');
  authUrl.searchParams.set('client_id', process.env.GOOGLE_CLIENT_ID);
  authUrl.searchParams.set('redirect_uri', 'https://myapp.com/callback');
  authUrl.searchParams.set('response_type', 'code');
  authUrl.searchParams.set('scope', 'openid email profile');
  authUrl.searchParams.set('state', generateState());
  res.redirect(authUrl.toString());
});

// 2. Callback handling
app.get('/callback', async (req, res) => {
  const { code, state } = req.query;
  verifyState(state);

  // Token exchange
  const tokenResponse = await fetch('https://oauth2.googleapis.com/token', {
    method: 'POST',
    body: new URLSearchParams({
      client_id: process.env.GOOGLE_CLIENT_ID,
      client_secret: process.env.GOOGLE_CLIENT_SECRET,
      code,
      grant_type: 'authorization_code',
      redirect_uri: 'https://myapp.com/callback'
    })
  });

  const { access_token, id_token } = await tokenResponse.json();
  // Get user info and create session
});

Grant Types

Grant TypeUse Case
Authorization CodeWeb apps (most common)
PKCESPA, mobile apps
Client CredentialsServer-to-server communication
Device CodeSmart TV and input-limited devices

Choosing an Authentication Method

Application TypeRecommended Method
Traditional Web App (Server-Side Rendering)Session Authentication
SPA + APIJWT (Short-lived Access Token + Refresh Token)
Mobile AppJWT or OAuth 2.0 (PKCE)
Third-party Login (Login with Google, etc.)OAuth 2.0 / OpenID Connect
Microservice-to-Microservice CommunicationJWT or OAuth 2.0 (Client Credentials)

Summary

The choice of authentication method depends on the type of application, security requirements, and scalability requirements. Session authentication is simple to implement and easy to control, while JWT is stateless and easy to scale. OAuth 2.0 is optimal for third-party authentication and API integration. Understand the characteristics of each method and choose the appropriate one for your use case.

← Back to list