API Authentication Methods: API Keys, JWT, OAuth 2.0 Explained

Compare the main API authentication methods — API keys, JWT, OAuth 2.0, and session cookies — and learn when to use each one in your applications.

By Belqassim Djafer · Published · Updated

Why API Authentication Matters

Every API that serves private data or triggers actions must verify the identity of the caller. Poor authentication is consistently in the OWASP Top 10 and is the cause of most significant data breaches. Understanding when to use each authentication method — and how to implement it correctly — is a core skill for every developer who builds or consumes APIs.

API Keys

The simplest authentication mechanism: a random token generated by the server and given to the client.

GET /api/data HTTP/1.1
Host: api.example.com
Authorization: Bearer sk_live_1234abcd5678efgh

Or as a query parameter (less secure, appears in logs):

GET /api/data?api_key=sk_live_1234abcd5678efgh

When to Use API Keys

  • Machine-to-machine communication between servers
  • Public APIs where users register for access
  • Simple access control without user identity requirements (the key identifies an app, not a person)
  • Stripe, SendGrid, Google Maps, OpenAI all use API keys

Security Best Practices

// Always pass in headers, never in URLs
const response = await fetch("https://api.example.com/data", {
  headers: {
    "Authorization": `Bearer ${process.env.API_KEY}`, // From env, not hardcoded
  }
});
  • Store in environment variables, never in source code
  • Rotate keys periodically and immediately upon suspected exposure
  • Restrict keys by IP address or scope when the provider allows it
  • Use different keys per environment (dev, staging, production)

JWT (JSON Web Tokens)

JWT is a compact, self-contained token format that encodes claims (user identity, roles, expiry) as a signed JSON payload.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4iLCJpYXQiOjE1MTYyMzkwMjJ9.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

The three base64url-encoded parts are:

  1. Header: algorithm and type
  2. Payload: claims (user ID, roles, expiry)
  3. Signature: HMAC or RSA signature for verification
// Decoded payload
{
  "sub": "user_123",
  "name": "Alice",
  "roles": ["admin"],
  "iat": 1716000000,
  "exp": 1716086400
}

JWT Authentication Flow

1. User logs in with username/password
2. Server validates credentials, generates JWT signed with secret key
3. Server returns JWT to client
4. Client stores JWT (memory or httpOnly cookie)
5. Client sends JWT in Authorization header for subsequent requests
6. Server validates signature without database lookup (stateless)

When to Use JWT

  • Stateless APIs: the server doesn't need to store session data
  • Microservices: tokens can be validated by any service that has the public key
  • Short-lived access tokens (15 min) paired with long-lived refresh tokens

JWT Security Pitfalls

// Never use algorithm "none" — it disables signature verification
// Never trust the "alg" field in the header
// Always verify the signature with the correct key
// Always validate exp (expiry)

import jwt from "jsonwebtoken";

// Correct: specify allowed algorithms explicitly
const payload = jwt.verify(token, process.env.JWT_SECRET, {
  algorithms: ["HS256"],     // Explicitly allow only HS256
  issuer: "api.example.com", // Validate issuer
  audience: "app.example.com" // Validate audience
});

Access Tokens + Refresh Tokens

Access token:  short-lived (15 min), stored in memory
Refresh token: long-lived (7–30 days), stored in httpOnly cookie

Flow:
1. Auth: returns access + refresh token
2. API call with access token
3. Access token expires → use refresh token to get new access token
4. Refresh token expires → user must log in again

OAuth 2.0

OAuth 2.0 is an authorisation framework that allows a user to grant a third-party application limited access to their resources without sharing their password.

The 4 OAuth 2.0 Grant Types

Grant Type Use Case
Authorization Code Web apps with a server side (most secure)
Authorization Code + PKCE SPAs and mobile apps
Client Credentials Server-to-server (no user involved)
Device Code Smart TVs, CLI tools

Authorization Code Flow (simplified)

1. Your app redirects user to OAuth provider:
   https://github.com/login/oauth/authorize?
     client_id=abc&
     redirect_uri=https://app.example.com/callback&
     scope=read:user&
     state=random_csrf_token

2. User authenticates at GitHub, approves scopes
3. GitHub redirects back with: ?code=TEMP_CODE&state=random_csrf_token
4. Your server exchanges code for access token (server-to-server):
   POST https://github.com/login/oauth/access_token
     client_id, client_secret, code
5. Response: { access_token: "gho_...", token_type: "bearer" }
6. Use access token to call GitHub API on behalf of user

When to Use OAuth 2.0

  • "Login with Google/GitHub/etc." in your app
  • Accessing a user's data from another service (read their calendar, post to their social media)
  • When you need fine-grained permission scopes

Session Cookies (Traditional)

1. User logs in → server creates session in database
2. Server sends Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Lax
3. Browser automatically sends cookie with every request to same origin
4. Server looks up session in database to identify user

Best for: traditional web applications with a single server, where you need immediate session revocation (logout).

Comparison

Method Stateless User Identity Revocable Best For
API Key ✅ App/service Manual key rotation M2M, public APIs
JWT ✅ User + claims Not until expiry Stateless APIs, microservices
OAuth 2.0 ✅ User (via provider) Via token endpoint Third-party auth, social login
Session Cookie ❌ DB lookup User Immediately Traditional web apps

Use our JWT Decoder to inspect JWT tokens and understand their claims without needing to write code.

Conclusion

No single authentication method is universally best. API keys are simple and reliable for M2M scenarios. JWT enables stateless, distributed authentication. OAuth 2.0 handles delegated user access. Session cookies provide immediate revocability for traditional apps. The most secure implementations use HTTPS everywhere, short token lifetimes, and the principle of least privilege.

Related Tools