Two Questions, Often Confused
Authentication answers “who are you” — verifying identity. Authorization answers “what are you allowed to do” — determining permissions. Conflating them is a common source of security bugs, like assuming a valid authentication token implies the bearer is authorized for every action they attempt.
Token-Based Authentication
Most modern APIs use bearer tokens — typically JWTs or opaque tokens — sent in an Authorization header. JWTs carry their claims within the token itself and can be verified without a database lookup, which is fast but means a compromised or leaked token remains valid until it expires; opaque tokens require a lookup but can be revoked instantly, a meaningful trade-off depending on your risk tolerance.
Short-Lived Access Tokens, Longer-Lived Refresh Tokens
Issuing short-lived access tokens (minutes to an hour) paired with a longer-lived refresh token limits the damage window if an access token leaks, while avoiding forcing users to re-authenticate constantly. Refresh tokens need stronger protection — store them in httpOnly cookies where possible, never in client-side accessible storage.
Never Trust Client-Side Authorization Checks
Hiding a button in your UI for users without permission is a UX nicety, not a security control. Every authorization decision must be enforced on the server, on every request, regardless of what the client claims about the current user’s role or permissions.
Scope Tokens Narrowly
A token that grants blanket access to your entire API is a bigger liability than one scoped to exactly what the requesting client needs. OAuth2 scopes let you issue tokens limited to specific actions or resources — a mobile app reading user data doesn’t need a token that could also delete other users’ accounts.
Rate Limiting and Abuse Prevention
Authentication endpoints specifically need aggressive rate limiting — login and password reset endpoints are prime targets for credential stuffing and brute force attacks. Generic API rate limiting protects against abuse broadly, but auth endpoints warrant tighter limits than the rest of your API.
Practical Checklist
- Validate and verify tokens on every request — never trust a token’s claims without cryptographic verification.
- Use short-lived access tokens with a secure refresh mechanism.
- Enforce authorization server-side, on every endpoint, without exception.
- Apply stricter rate limits specifically to authentication endpoints.