Token Management

Best practices for token management and handling authentication errors

This guide covers best practices for managing access tokens, handling token refresh, and troubleshooting authentication errors.


Token Caching

Always cache tokens to avoid unnecessary token requests. Tokens are valid for 1 hour.

  1. Cache the token after successful retrieval

  2. Track expiration using the expires_in value

  3. Refresh proactively before expiration (5-minute buffer recommended)

  4. Handle failures by requesting a new token

public class TokenCache
{
    private string _token;
    private DateTime _expiry;
    private readonly SemaphoreSlim _lock = new(1, 1);

    public async Task<string> GetTokenAsync(Func<Task<TokenResponse>> requestToken)
    {
        // Check if token is valid (with 5-minute buffer)
        if (!string.IsNullOrEmpty(_token) && DateTime.UtcNow < _expiry.AddMinutes(-5))
        {
            return _token;
        }

        await _lock.WaitAsync();
        try
        {
            // Double-check after acquiring lock
            if (!string.IsNullOrEmpty(_token) && DateTime.UtcNow < _expiry.AddMinutes(-5))
            {
                return _token;
            }

            var response = await requestToken();
            _token = response.AccessToken;
            _expiry = DateTime.UtcNow.AddSeconds(response.ExpiresIn);

            return _token;
        }
        finally
        {
            _lock.Release();
        }
    }
}

Why Cache Tokens?

Without Caching
With Caching

Token request every API call

One request per hour

Added latency (~100-300ms)

No extra latency

Risk of rate limiting

Minimal auth server load


Token Refresh Strategies

Proactive Refresh

Refresh the token before it expires to avoid failed API calls:

Reactive Refresh

Refresh when you receive a 401 Unauthorized response:


Security Best Practices

1. Secure Credential Storage

triangle-exclamation

Recommended approaches:

Environment
Storage Method

Development

Environment variables, .env files (gitignored)

Production

Secret managers (AWS Secrets Manager, Azure Key Vault, HashiCorp Vault)

CI/CD

Pipeline secrets, secure variables

2. Use HTTPS Only

All API communication must use HTTPS. HTTP requests will be rejected or redirected.

3. Validate Token Responses

Always check for errors in token responses:

4. Implement Token Isolation

If your application serves multiple clients, isolate tokens:

5. Log Authentication Events

Log authentication events for debugging (but never log secrets):


Error Handling

Token Request Errors

Error
Cause
Solution

invalid_client

Wrong client_id or client_secret

Verify credentials

invalid_request

Missing required parameters

Check request format

invalid_scope

Scope doesn't exist or not authorized

Verify scope name

unsupported_grant_type

Wrong grant_type value

Use client_credentials

API Authentication Errors

Status
Meaning
Action

401 Unauthorized

Token invalid or expired

Refresh token and retry

403 Forbidden

Token valid but lacks permission

Check scope/permissions

Retry Logic

Implement exponential backoff for transient errors:


Troubleshooting

"invalid_client" Error

  1. Verify client_id - Check for typos or extra whitespace

  2. Verify client_secret - Ensure you're using the correct secret

  3. Check environment - Make sure you're using the right credentials for the environment (prod vs QA)

"invalid_scope" Error

  1. Check scope format - Should be default-m2m-resource-server-p2hkah/admin:internal

  2. Verify authorization - Confirm your client is authorized for the requested scope

  3. Contact support - If the scope should be valid, contact [email protected]

Token Works in Postman but Not in Code

  1. Check Content-Type - Must be application/x-www-form-urlencoded

  2. Verify encoding - Special characters in credentials must be URL-encoded

  3. Check for whitespace - Trim any leading/trailing whitespace from credentials

401 Errors After Token Refresh

  1. Check clock sync - Ensure your server's clock is synchronized (NTP)

  2. Verify token - Decode the JWT at jwt.ioarrow-up-right to check claims

  3. Check expiration - The exp claim should be in the future

Intermittent Authentication Failures

  1. Implement retry logic - Network issues can cause transient failures

  2. Check for race conditions - Ensure token refresh is thread-safe

  3. Monitor token expiry - Refresh tokens proactively, not reactively


Complete Example

A production-ready token management implementation:

Last updated