WEB API's Lesson 17 – Authentication Basics | Dataplexa
Web APIs · Lesson 17

Authentication Basics

Master the core patterns that protect API endpoints and verify user identity across millions of applications.

GitHub serves over 100 million developers through its APIs every day. Each API call carries credentials that determine whether you get data or a 401 Unauthorized error. Without authentication, APIs would be chaos—anyone could access anything, modify user data, or drain system resources. That fundamental security gate keeps the modern web functioning.

Authentication answers one critical question: who is making this request? It sits at the entry point of every protected API endpoint, validating credentials before any business logic runs. Think of it as checking IDs at a concert venue—no valid ticket means no entry, regardless of what happens inside.

The challenge grows complex fast. APIs serve mobile apps, web browsers, server-to-server integrations, and automated scripts. Each client type needs different authentication approaches. A banking app requires stronger security than a weather API. Real-time chat needs fast credential checks while payment processing demands bulletproof validation.

The Authentication Problem Space

Every API request arrives as anonymous traffic until proven otherwise. Your server sees an IP address, some headers, and a request body. It has no inherent way to know whether this comes from a legitimate user, a malicious bot, or an automated script running wild.

Traditional web applications handle this through sessions. Users log in once, the server creates a session ID, stores user data in memory or a database, and sends the session ID back as a cookie. Every subsequent request includes that cookie, letting the server look up user information.

APIs break this model completely. Mobile apps cannot rely on cookies. Server-to-server communication has no concept of browser sessions. Single-page applications make hundreds of API calls from JavaScript code that traditional session management cannot handle efficiently.

Why Sessions Fail for APIs
Sessions require server-side state storage and cookie support. APIs serve mobile apps that cannot store cookies, run across multiple servers that do not share memory, and need to scale horizontally without sticky sessions. The session model collapses under API requirements.
The APIForge Security team discovered this firsthand when their developer portal launched. They initially used Django sessions for their API endpoints. Mobile developers complained immediately—iOS and Android apps could not maintain sessions. The team had to rethink their entire authentication strategy.

Modern API authentication solves this through stateless credentials. Instead of server-side sessions, each request carries everything needed to verify the user. The server validates credentials without looking up external state, processes the request, and forgets about the interaction.

Core Authentication Patterns

Authentication patterns evolved to handle different security requirements and client capabilities. Understanding the five core approaches helps you choose the right method for specific scenarios.
1
Basic Authentication
Concept
Header-based
Simple credentials
RFC 7617
Low security
Basic Authentication encodes username and password in base64 and sends them in the Authorization header with every request. Despite the name, it provides minimal security since base64 is encoding, not encryption. Anyone intercepting the request can decode credentials instantly.

The pattern works for internal tools, development environments, or APIs where HTTPS provides the real security layer. Many CI/CD systems and developer tools use Basic Auth because it requires no complex token management—just embed credentials directly in HTTP headers.

GET /api/users/profile HTTP/1.1
Host: api.apiforge.com
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Content-Type: application/json

# The APIForge DevOps team uses Basic Auth for internal monitoring tools
# Base64 decode reveals: username:password
# Simple but requires HTTPS to prevent credential theft
HTTP/1.1 200 OK Content-Type: application/json Server: nginx/1.20.2 Date: Wed, 15 Nov 2023 14:22:33 GMT Content-Length: 156 { "user_id": "usr_4k9x2m", "email": "sarah@apiforge.com", "team": "DevOps", "last_login": "2023-11-15T14:20:15Z", "permissions": ["monitor", "deploy"] }
What just happened?
The client encoded credentials as base64 and included them in the Authorization header. The server decoded the credentials, verified them against user records, and returned profile data. The authentication happens on every single request. Try this: Open browser dev tools and look for Authorization headers in API requests—many sites use this pattern for admin tools.
Authentication Method What it does APIForge use case
Basic Authentication Sends base64 encoded username:password in header Internal monitoring dashboard API access
API Keys Uses unique tokens to identify API consumers Developer platform access and rate limiting
Bearer Tokens Carries access tokens representing user sessions Mobile app user authentication
OAuth 2.0 Delegates authentication to external providers Sign in with Google/GitHub integration
JWT (JSON Web Tokens) Self-contained tokens with embedded user data Microservices user context sharing
API Keys represent the most common authentication method for developer-facing APIs. Instead of user credentials, clients receive a unique key that identifies their application or account. The key acts as both authentication (proving identity) and authorization (defining access levels).

Stripe pioneered this approach for payment APIs. Developers get publishable keys for frontend code and secret keys for server-side operations. The key structure immediately tells Stripe what environment and permissions apply. This pattern now dominates SaaS APIs because it separates user accounts from API access cleanly.

GET /api/projects HTTP/1.1
Host: api.apiforge.com  
X-API-Key: af_live_sk_2Qq8x9PmN4vK8jW3R5tY7sC1mH6fD9eL
Content-Type: application/json

# APIForge Backend team issues API keys for external developer access
# Keys include environment prefix (af_live_) and permission scope (sk_)
# Server validates key and applies associated rate limits and permissions
HTTP/1.1 200 OK Content-Type: application/json X-RateLimit-Limit: 1000 X-RateLimit-Remaining: 847 X-RateLimit-Reset: 1700059353 { "projects": [ { "id": "proj_8xKm2vN", "name": "E-commerce API", "created_at": "2023-10-15T09:30:00Z", "endpoints": 24 }, { "id": "proj_5nR9qWt", "name": "User Dashboard API", "created_at": "2023-11-02T16:45:00Z", "endpoints": 12 } ] }
What just happened?
The API key identified the developer account and granted access to project data. The server also returned rate limit headers showing current usage. The key structure (af_live_sk_) tells the server this is a live environment secret key with full permissions. Try this: Check how your favorite APIs handle keys—most include environment and permission hints directly in the key format.

Bearer Token Authentication

Bearer tokens solve the core problem of user-specific API access. Instead of sending actual credentials with each request, users authenticate once to receive a token representing their session. The token carries enough information to verify identity and permissions without database lookups.

The flow works like a concert wristband system. You show ID at the entrance, get a wristband, then use only the wristband for access throughout the event. API clients authenticate with username/password once, receive a bearer token, then include that token in subsequent requests until it expires.

Twitter's API exemplifies this pattern. Mobile apps authenticate users through OAuth, receive access tokens, then make API calls with those tokens. The tokens expire periodically, forcing re-authentication and limiting damage if credentials leak.

Token Lifecycle Management
Tokens need expiration, renewal, and revocation mechanisms. Short-lived tokens reduce security risk but increase authentication overhead. Long-lived tokens improve performance but extend breach windows. Most systems use refresh tokens—long-lived tokens that generate new short-lived access tokens automatically.
The APIForge Frontend team implemented bearer tokens for their developer dashboard. Users log in through the web interface, receive JWT tokens valid for 24 hours, then use those tokens for all API calls. The approach eliminated the need for session storage while providing seamless user experience.
// APIForge dashboard login flow
const response = await fetch('/api/auth/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    email: 'dev@startup.com',
    password: 'secure_password'
  })
});

const { access_token } = await response.json();
localStorage.setItem('token', access_token);
{ "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNDIzIiwiZW1haWwiOiJkZXZAc3RhcnR1cC5jb20iLCJleHAiOjE3MDAwNTkzNTN9.8xKJF2vR9qN5mH3tY7wZ1cL6pQ4sE2dA9fX8vB0gU2i", "token_type": "Bearer", "expires_in": 86400, "user": { "id": 423, "email": "dev@startup.com", "team": "Engineering" } }
What just happened?
The client sent login credentials and received a JWT access token valid for 24 hours (86400 seconds). The token encodes user information and can be verified without database calls. The frontend stores this token and includes it in future API requests. Try this: Decode the JWT token using jwt.io to see the embedded user data.

Authentication Headers and Standards

HTTP headers carry authentication data in standardized formats that servers and clients universally understand. The Authorization header serves as the primary mechanism, with specific schemes defining how credentials are formatted and processed.

The header follows a simple pattern: Authorization: <scheme> <credentials>. The scheme tells the server how to interpret the credentials. Basic means base64-encoded username:password. Bearer indicates a token-based system. Custom schemes handle proprietary authentication methods.

Standard Header
Authorization: Bearer token123
Universally supported, works with all HTTP clients and proxies
Custom Header
X-API-Key: af_sk_123
Easier to implement, may conflict with proxies or security tools
Some APIs use custom headers like X-API-Key or X-Auth-Token for simplicity. While easier to implement, custom headers can cause issues with HTTP proxies, load balancers, or security tools that understand standard Authorization headers. The trade-off favors standards compliance for public APIs and custom headers for internal systems.

Multiple authentication schemes can coexist in the same API. GitHub's API accepts both personal access tokens and OAuth tokens through the Authorization header, plus legacy username/password through Basic auth. The server examines the scheme and routes to appropriate validation logic.

# Different authentication schemes for the same APIForge endpoint

# Bearer token (JWT)
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

# Basic authentication  
Authorization: Basic dGVzdEBhcGlmb3JnZS5jb206cGFzc3dvcmQ=

# API key (custom scheme)
Authorization: APIKey af_live_sk_2Qq8x9PmN4vK8jW3R5tY
HTTP/1.1 200 OK Content-Type: application/json X-Auth-Method: Bearer-JWT X-User-ID: usr_4k9x2m { "authentication": { "method": "Bearer token", "user_id": "usr_4k9x2m", "expires_at": "2023-11-16T14:22:33Z", "scopes": ["read:projects", "write:projects"] }, "message": "Authentication successful" }
What just happened?
The server accepted a Bearer token, validated it as a JWT, extracted user information, and returned authentication details. The response headers show which authentication method was used and the authenticated user ID. Different schemes provide the same functionality but with varying security and complexity levels. Try this: Use curl with different Authorization header formats to see how APIs handle multiple authentication schemes.

Authentication vs Authorization

Authentication and authorization work together but solve different problems. Authentication asks "who are you?" while authorization asks "what can you do?" The distinction becomes critical when building APIs that serve users with different permission levels.

Think of airport security: authentication happens when you show ID at check-in—proving you are who you claim to be. Authorization happens at the gate when they verify your boarding pass allows access to that specific flight. Many systems conflate these concerns, leading to security vulnerabilities and inflexible permission models.

APIs handle this separation through layered validation. Authentication middleware verifies credentials and identifies the user. Authorization middleware checks whether that user can perform the requested action on the specified resource. The separation enables fine-grained permissions and audit trails.

Common Authentication Mistakes
Mixing authentication and authorization logic creates brittle systems. Storing permissions in JWTs makes revocation impossible—fired employees keep access until tokens expire. Using the same credentials for authentication and API access eliminates audit trails and fine-grained control.
The APIForge Product team learned this separation lesson during their beta launch. Initially, they embedded user roles directly in authentication tokens. When they needed to revoke beta access for specific features, they had to invalidate all user tokens and force re-authentication. The team now separates authentication (user identity) from authorization (feature access).
Authentication Only
User proves identity through credentials. System knows who made the request but not what they can access. Leads to binary access control—all or nothing permissions.
Authentication + Authorization
User identity plus permission checking at every endpoint. Enables role-based access, resource-level permissions, and dynamic security policies that adapt to user context.

Security Considerations

API authentication faces unique security challenges that traditional web authentication never encounters. Mobile clients store credentials locally where users can extract them. Server-to-server communication crosses network boundaries where packets might be intercepted. Token-based systems need defense against replay attacks and credential stuffing.

The fundamental principle: treat all network traffic as hostile. HTTPS provides transport security but cannot protect against application-layer attacks. Stolen tokens work perfectly until they expire. Weak authentication schemes enable account takeovers that compromise entire user bases.

Rate limiting becomes essential for authentication endpoints. Password-based login attempts can be brute-forced if servers process unlimited requests. Token validation endpoints can be overwhelmed by replay attacks. Smart attackers distribute attacks across multiple IP addresses, bypassing simple rate limiting.

Production Security Checklist
Always use HTTPS for authentication endpoints. Implement exponential backoff for failed login attempts. Set reasonable token expiration times—24 hours for user tokens, 1 hour for high-privilege operations. Log all authentication events for security monitoring. Never store passwords in plain text or reversible encryption.
Real-world attacks target authentication systems constantly. The 2019 Capital One breach exploited weak server-to-server authentication that allowed access to customer data. GitHub regularly blocks millions of credential stuffing attempts against their authentication API. Slack implemented additional verification for high-risk login attempts after detecting automated account takeover campaigns.

The APIForge Security team implements defense in depth: HTTPS for transport security, bcrypt for password hashing, JWT tokens with short expiration, rate limiting on authentication endpoints, and monitoring for suspicious patterns. Each layer provides partial protection, but together they create robust security.

Implementation Patterns

Authentication implementation varies dramatically based on client types and security requirements. Single-page applications need different approaches than mobile apps, which differ from server-to-server integration. Understanding common patterns helps choose appropriate authentication strategies.

Web applications typically use session-based authentication with API fallbacks. Users authenticate through traditional login forms that create server sessions. JavaScript code accesses APIs through session cookies or by exchanging session data for API tokens. This hybrid approach provides familiar UX while enabling API access.

Mobile applications require token-based authentication exclusively. Apps cannot rely on cookies or server sessions. Users authenticate once during app login, receive long-lived refresh tokens stored in secure device storage, and exchange refresh tokens for short-lived access tokens as needed. The pattern enables offline-capable apps with secure credential storage.

// APIForge mobile app authentication flow
class AuthManager {
  async login(email, password) {
    const response = await fetch('/api/auth/token', {
      method: 'POST',
      body: JSON.stringify({ email, password })
    });
    
    const { access_token, refresh_token } = await response.json();
    await this.storeTokens(access_token, refresh_token);
    return access_token;
  }
}
{ "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNDIzIiwiZXhwIjoxNzAwMDU5MzUzfQ", "refresh_token": "rt_8xKJF2vR9qN5mH3tY7wZ1cL6pQ4sE2dA9fX8vB0gU2i", "token_type": "Bearer", "expires_in": 3600, "scope": "read write" }
What just happened?
The mobile app exchanged user credentials for both access and refresh tokens. The access token expires in 1 hour for security, while the refresh token enables getting new access tokens without user re-authentication. This pattern balances security with user experience—frequent token refresh without constant login prompts. Try this: Examine how mobile apps on your phone handle login persistence across app restarts.
Server-to-server authentication prioritizes automation and security over user experience. Systems authenticate using API keys, client certificates, or OAuth client credentials flow. No human interaction exists, so authentication must work reliably without manual intervention while providing strong security guarantees.

The choice between authentication patterns depends on your specific requirements: user experience needs, security requirements, client capabilities, and operational complexity. Most modern applications implement multiple patterns—OAuth for third-party integrations, JWT tokens for mobile apps, and API keys for server-to-server communication.

Quiz

1. The APIForge Backend team needs to authenticate mobile app requests that cannot use browser cookies. What makes an authentication method "stateless" for APIs?

2. Why is Basic Authentication considered insecure compared to Bearer tokens?

3. The APIForge Security team wants to implement proper access control for their developer platform. What is the key difference between authentication and authorization?

Up Next
Authorization
APIForge implements role-based access control and resource-level permissions for their developer platform.