Authentication Methods
February 22, 2025 32174b4 Edit this page

Authentication Methods 🗄️ Archived

Comprehensive guide to all supported authentication methods

Learn about all available authentication methods and when to use each.

Overview

We support multiple authentication methods:

  1. JWT Tokens - For web and mobile applications
  2. API Keys - For server-to-server communication
  3. OAuth 2.0 - For third-party integrations
  4. Session-based - For traditional web applications

JWT Authentication

Obtaining a JWT Token

curl -X POST https://api.example.com/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "securepassword"
  }'

Response:

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600
}

Using JWT Tokens

Include the access token in the Authorization header:

curl https://api.example.com/v1/resources \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Refreshing Tokens

When the access token expires, use the refresh token:

curl -X POST https://api.example.com/v1/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }'

Python Implementation

import requests
from datetime import datetime, timedelta

class AuthManager:
    def __init__(self, base_url):
        self.base_url = base_url
        self.access_token = None
        self.refresh_token = None
        self.token_expiry = None
    
    def login(self, email, password):
        response = requests.post(
            f"{self.base_url}/auth/login",
            json={"email": email, "password": password}
        )
        data = response.json()
        
        self.access_token = data['access_token']
        self.refresh_token = data['refresh_token']
        self.token_expiry = datetime.now() + timedelta(
            seconds=data['expires_in']
        )
    
    def get_token(self):
        # Refresh if token is expired or about to expire
        if not self.access_token or datetime.now() >= self.token_expiry:
            self.refresh()
        
        return self.access_token
    
    def refresh(self):
        response = requests.post(
            f"{self.base_url}/auth/refresh",
            json={"refresh_token": self.refresh_token}
        )
        data = response.json()
        
        self.access_token = data['access_token']
        self.token_expiry = datetime.now() + timedelta(
            seconds=data['expires_in']
        )
    
    def make_request(self, method, endpoint, **kwargs):
        token = self.get_token()
        headers = kwargs.get('headers', {})
        headers['Authorization'] = f'Bearer {token}'
        kwargs['headers'] = headers
        
        return requests.request(method, f"{self.base_url}{endpoint}", **kwargs)

API Key Authentication

Creating an API Key

curl -X POST https://api.example.com/v1/api-keys \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production API Key",
    "scopes": ["read:resources", "write:resources"]
  }'

Response:

{
  "id": "key_abc123",
  "name": "Production API Key",
  "key": "sk_live_xyz789...",
  "scopes": ["read:resources", "write:resources"],
  "created_at": "2025-02-22T10:00:00Z"
}

⚠️ Important: Save the key securely. It won’t be shown again.

Using API Keys

Two methods:

1. Header (Recommended):

curl https://api.example.com/v1/resources \
  -H "X-API-Key: sk_live_xyz789..."

2. Query Parameter:

curl "https://api.example.com/v1/resources?api_key=sk_live_xyz789..."

API Key Best Practices

import os

# Store in environment variables
API_KEY = os.environ.get('API_KEY')

# Never commit to version control
# Add to .gitignore
echo "API_KEY=sk_live_xyz789..." >> .env
echo ".env" >> .gitignore

# Rotate keys regularly
def rotate_api_key():
    # Create new key
    new_key = create_api_key()
    
    # Update environment
    update_environment_variable('API_KEY', new_key)
    
    # Delete old key after transition period
    schedule_deletion(old_key_id, days=7)

OAuth 2.0

Authorization Code Flow

Step 1: Redirect user to authorization URL

https://api.example.com/oauth/authorize?
  response_type=code&
  client_id=YOUR_CLIENT_ID&
  redirect_uri=https://your-app.com/callback&
  scope=read:resources write:resources&
  state=random_state_string

Step 2: User authorizes your app

After authorization, user is redirected to:

https://your-app.com/callback?
  code=AUTH_CODE&
  state=random_state_string

Step 3: Exchange code for tokens

curl -X POST https://api.example.com/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=AUTH_CODE" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "redirect_uri=https://your-app.com/callback"

Client Credentials Flow

For machine-to-machine authentication:

curl -X POST https://api.example.com/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "scope=read:resources"

OAuth Implementation Example

from requests_oauthlib import OAuth2Session

class OAuthClient:
    def __init__(self, client_id, client_secret, redirect_uri):
        self.client_id = client_id
        self.client_secret = client_secret
        self.redirect_uri = redirect_uri
        self.authorization_base_url = 'https://api.example.com/oauth/authorize'
        self.token_url = 'https://api.example.com/oauth/token'
    
    def get_authorization_url(self):
        oauth = OAuth2Session(
            self.client_id,
            redirect_uri=self.redirect_uri,
            scope=['read:resources', 'write:resources']
        )
        authorization_url, state = oauth.authorization_url(
            self.authorization_base_url
        )
        return authorization_url, state
    
    def fetch_token(self, authorization_response):
        oauth = OAuth2Session(self.client_id, redirect_uri=self.redirect_uri)
        token = oauth.fetch_token(
            self.token_url,
            authorization_response=authorization_response,
            client_secret=self.client_secret
        )
        return token
    
    def make_request(self, token, url):
        oauth = OAuth2Session(self.client_id, token=token)
        return oauth.get(url)

Session-Based Authentication

Login

curl -X POST https://api.example.com/v1/session/login \
  -H "Content-Type: application/json" \
  -c cookies.txt \
  -d '{
    "email": "user@example.com",
    "password": "securepassword"
  }'

Making Authenticated Requests

curl https://api.example.com/v1/resources \
  -b cookies.txt

Logout

curl -X POST https://api.example.com/v1/session/logout \
  -b cookies.txt

Security Considerations

Token Storage

MethodSecurityUse Case
Memory (variable)✅ Most SecureShort-lived sessions
SessionStorage✅ SecureSingle-tab applications
HttpOnly Cookie✅ SecureServer-rendered apps
LocalStorage⚠️ Less SecureOnly for non-sensitive tokens

Token Rotation

Implement automatic token rotation:

class TokenManager {
  constructor() {
    this.token = null;
    this.refreshTimer = null;
  }
  
  setToken(token, expiresIn) {
    this.token = token;
    
    // Refresh 5 minutes before expiry
    const refreshTime = (expiresIn - 300) * 1000;
    this.refreshTimer = setTimeout(() => {
      this.refreshToken();
    }, refreshTime);
  }
  
  async refreshToken() {
    const response = await fetch('/auth/refresh', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        refresh_token: this.refreshToken
      })
    });
    
    const data = await response.json();
    this.setToken(data.access_token, data.expires_in);
  }
}

Choosing the Right Method

ScenarioRecommended Method
Web/Mobile AppJWT
Server-to-ServerAPI Key or Client Credentials
Third-Party IntegrationOAuth 2.0
Traditional Web AppSession-based
Embedded DevicesAPI Key
Temporary AccessJWT with short expiry