Published May 29, 2026 ยท 8 min read ยท ๐ท๏ธ Security
API Authentication Methods Explained
Authentication is critical for API security. This guide compares the main methods โ API Keys, Basic Auth, Bearer Tokens, OAuth 2.0, and JWT โ with pros, cons, and when to use each.
API Keys
Simple static keys assigned to clients:
curl -H "X-API-Key: your-api-key-here" https://api.example.com/data
Pros:
- Simple to implement
- Easy to understand and debug
- Good for server-to-server communication
Cons:
- No expiration (unless you implement it)
- If leaked, full access until revoked
- No granular permissions (all-or-nothing)
Best for: Internal services, simple third-party integrations
Basic Authentication
Username and password sent with each request (Base64 encoded, not encrypted):
# Encoding: Base64("username:password")
curl -H "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=" https://api.example.com/
# Or use curl's built-in auth
curl -u username:password https://api.example.com/
Pros:
- Extremely simple
- Universally supported
- Good for testing
Cons:
- Credentials sent with every request
- Must always use HTTPS
- No built-in expiration
Never use Basic Auth over HTTP. Without TLS, credentials are sent in plain text visible to anyone watching network traffic.
Bearer Tokens (Token Authentication)
A token is issued after authentication and sent with each request:
# After login, server returns token
# Client stores token and sends with requests
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." https://api.example.com/data
Pros:
- Credentials only sent once
- Token can expire
- Easier to revoke (delete from database)
Cons:
- Requires database lookup to validate (unless using JWT)
- State must be stored server-side
JWT (JSON Web Tokens)
Self-contained tokens that include the data payload (stateless):
// JWT has three parts: header.payload.signature
// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEyMywicm9sZSI6ImFkbWluIn0.signature
// Server verifies signature without database lookup
const payload = jwt.verify(token, SECRET_KEY);
console.log(payload.userId); // 123
Structure:
- Header: Algorithm and token type
- Payload: Claims (userId, role, exp, etc.)
- Signature: Prevents tampering
Pros:
- Stateless โ no database lookup needed
- Can include user data and permissions
- Works across services (microservices)
Cons:
- Can't revoke until expiration (use short expiry + refresh tokens)
- Payload is visible (don't store sensitive data)
- Larger than API keys
OAuth 2.0
A proper authorization framework for third-party access:
# 1. User clicks "Login with Google"
# 2. Redirect to Google with client_id and redirect_uri
GET https://accounts.google.com/o/oauth2/v2/auth?
client_id=YOUR_CLIENT_ID&
redirect_uri=https://yourapp.com/callback&
response_type=code&
scope=openid%20profile%20email
# 3. Google redirects back with authorization code
# 4. Your server exchanges code for access token
POST https://oauth2.googleapis.com/token
{
code: "authorization_code",
client_id: "YOUR_CLIENT_ID",
client_secret: "YOUR_CLIENT_SECRET",
redirect_uri: "https://yourapp.com/callback",
grant_type: "authorization_code"
}
# 5. Response includes access token (and optionally refresh token)
{
access_token: "ya29....",
expires_in: 3600,
refresh_token: "refresh_token_here"
}
Grant Types:
- Authorization Code: Web apps (full flow)
- PKCE: Mobile/SPA apps (no client secret)
- Client Credentials: Server-to-server (no user)
- Refresh Token: Get new access tokens
Comparison Table
| Method | Complexity | Best For |
|---|---|---|
| API Keys | Low | Simple server-to-server |
| Basic Auth | Low | Testing, internal tools |
| Bearer Tokens | Medium | Session-based auth |
| JWT | Medium | Microservices, stateless auth |
| OAuth 2.0 | High | Third-party login, social auth |
Security Best Practices
- Always use HTTPS โ never send credentials over HTTP
- Use short token expiry โ 15-60 minutes for access tokens
- Implement refresh tokens โ allow re-authentication without re-login
- Store secrets securely โ environment variables, not in code
- Log authentication events โ detect anomalies
- Implement rate limiting โ prevent brute force attacks
- Rotate secrets โ change API keys periodically