Skip to content

18 Authentication Design

DodaTech 3 min read

title: Authentication Design in REST API Design — Complete Guide weight: 28 date: 2026-06-28 lastmod: 2026-06-28 description: Learn REST API authentication design including API keys, JWT tokens, OAuth2 flows, session-based auth, and token management best practices for secure APIs. tags: [api-development, rest]


Authentication design in REST APIs establishes how clients prove their identity, with JWT bearer tokens being the most common approach, followed by API keys for machine-to-machine communication and OAuth2 for delegated authorization.

```mermaid
flowchart TD
  A[Auth Methods] --> B[API Keys]
  A --> C[JWT Tokens]
  A --> D[OAuth 2.0]
  A --> E[Basic Auth]
  B --> F["X-API-Key: abc123"]
  C --> G["Authorization: Bearer eyJ..."]
  D --> H[Client Credentials / Auth Code]
  style A fill:#e1f5fe
  style C fill:#c8e6c9

API keys are simple static tokens sent as headers. They work well for server-to-server communication. JWT tokens are self-contained JSON objects signed by the server. They carry user identity and claims, eliminating database lookups on every request. OAuth2 is a protocol for delegated access where users authorize third-party applications.

Think of authentication methods like house keys. An API key is like a single master key that unlocks everything. A JWT token is like a hotel key card that expires and has limited access. OAuth2 is like a valet key that lets someone else park your car but not access the trunk.

Example: API Key Authentication

import requests

headers = {
    "X-API-Key": "sk_live_abc123def456"
}
response = requests.get(
    "https://api.example.com/users",
    headers=headers
)
print(f"Status: {response.status_code}")
print(f"User: {response.json()}")

Expected output:

Status: 200
User: [{"id": 1, "name": "Alice"}]

Example: JWT Token Authentication

import requests

# Obtain JWT token
login_data = {
    "username": "alice@example.com",
    "password": "securepassword123"
}
auth_response = requests.post(
    "https://api.example.com/auth/login",
    json=login_data
)
token = auth_response.json()["access_token"]
print(f"Token: {token[:20]}...")

# Use JWT for subsequent requests
headers = {"Authorization": f"Bearer {token}"}
response = requests.get(
    "https://api.example.com/users/me",
    headers=headers
)
print(f"User: {response.json()['name']}")

Expected output:

Token: eyJhbGciOiJIUzI1Ni...
User: Alice

Example: Token Refresh

import requests

def refresh_token(refresh_token_value):
    response = requests.post(
        "https://api.example.com/auth/refresh",
        json={"refresh_token": refresh_token_value}
    )
    return response.json()

# Simulate token refresh
tokens = {
    "access_token": "expired_token",
    "refresh_token": "valid_refresh_token"
}
new_tokens = refresh_token(tokens["refresh_token"])
print(f"New access token: {new_tokens['access_token'][:20]}...")
print(f"Expires in: {new_tokens['expires_in']} seconds")

Expected output:

New access token: eyJhbGciOiJIUzI1Ni...
Expires in: 3600 seconds

Common Mistakes

  1. Storing tokens insecurely on the client — Storing JWT tokens in localStorage makes them accessible to XSS attacks. Use httpOnly cookies for browser apps.
  2. Not expiring tokens — Tokens that never expire are a security risk if leaked. Use short-lived access tokens (15-60 minutes) with refresh tokens.
  3. Including sensitive data in JWT payloads — JWT payloads are base64-encoded, not encrypted. Do not include passwords or secrets.
  4. Using Basic Auth over HTTP — Basic Auth sends credentials as base64-encoded plaintext. Always use HTTPS. Prefer token-based auth over Basic Auth.
  5. Not validating token signatures — Always verify the JWT signature on every request. Accepting unsigned tokens allows forgery.

Practice Questions

  1. What is the difference between authentication and authorization?
  2. Why are JWT tokens preferred over session-based auth for REST APIs?
  3. What is the purpose of a refresh token?
  4. Why should you not store sensitive data in a JWT payload?
  5. Challenge: Implement a JWT authentication flow in Python that includes login, token verification, token refresh, and logout (token blacklist). Use the PyJWT library for signing and verification.

FAQ

What is the difference between JWT and OAuth2?

JWT is a token format. OAuth2 is an authorization protocol. They work together: OAuth2 can issue JWT tokens as access tokens.

Should I use access tokens or refresh tokens?

Use both. Access tokens are short-lived (15-60 min) for API access. Refresh tokens are long-lived (days) and used to obtain new access tokens without re-authentication.

How do I revoke a JWT token?

JWT tokens are stateless and cannot be revoked unless you maintain a blacklist. Short expiration times reduce the need for revocation.

What is the Authorization header format?

The format is: Authorization: . Common types: Bearer (JWT), Basic (username:password base64), and API-Key.

Should I use httpOnly cookies or Authorization header for browser apps?

httpOnly cookies are more secure against XSS attacks. The Authorization header is simpler for mobile apps. Both work with proper security measures.

Mini Project

Build a Python authentication module that supports API key, JWT, and Basic Auth methods. The module should include token generation, token validation, token refresh, and a rate-limited login endpoint. Include security measures like bcrypt password hashing and signature verification.

What's Next

Now learn about caching design in REST API Design.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro