Receiving Authorization in APIs: OAuth, API Keys, and Token-Based Access Explained

Receiving Authorization in APIs: OAuth, API Keys, and Token-Based Access Explained

One of the most confusing parts of working with APIs, especially for people just getting started, is figuring out exactly how “receiving authorization” actually works in practice. What does it mean to be authorized to call an API? How do you actually get that authorization, and what do you do with it once you have it? I want to break this down step by step, the way I wish someone had explained it to me early on.

Authorization vs. Authentication: Getting the Terms Straight

Before anything else, let’s clear up a common mix-up:

  • Authentication proves who you are (logging in with a username and password, for example).
  • Authorization determines what you’re allowed to do once your identity is confirmed.

Receiving authorization means being granted the specific permissions needed to perform an action or access a resource through the API — not just proving you’re a valid user.

The Main Ways APIs Grant Authorization

1. API Keys

The simplest method: the API provider issues you a unique key, and you attach it to every request, usually in a header like Authorization: Api-Key your_key_here or as a query parameter.

Pros: Simple to implement and understand. Cons: Keys rarely expire on their own, are easy to accidentally leak (in logs, front-end code, or public repos), and typically grant broad, all-or-nothing access.

Best used for: server-to-server communication where the key can be kept genuinely secret, not for anything running in a browser or mobile app.

2. Basic Authentication

A username and password (or a token acting as one) sent with every request, base64-encoded in the Authorization header. It’s simple but weak on its own — always pair it with HTTPS, and honestly, prefer token-based approaches whenever possible.

3. OAuth 2.0

OAuth 2.0 is the standard for delegated authorization — letting a user grant a third-party application limited access to their data without ever sharing their actual password with that application.

Here’s the general flow for the most common variant, the Authorization Code flow:

  1. The user clicks “Log in with [Service]” on a third-party app.
  2. They’re redirected to the actual service’s login page and log in there directly.
  3. The service asks the user to approve specific permissions (scopes) the app is requesting, like “read your profile” or “post on your behalf.”
  4. Once approved, the service redirects back to the third-party app with a temporary authorization code.
  5. The app exchanges that code (along with a client secret) for an access token.
  6. The app uses the access token to make authorized API calls on the user’s behalf.

Scopes are central to OAuth — they let users and providers limit exactly what an application can do, rather than granting full account access.

Refresh tokens let an app get a new access token once the old one expires, without forcing the user to log in again every time.

4. JWT (JSON Web Tokens)

A JWT is a compact, self-contained token that includes encoded claims about the user (like their ID, roles, and permissions) along with a cryptographic signature. Because the server can verify the signature without a database lookup, JWTs are fast and scale well.

A typical JWT-based authorization flow:

  1. User logs in with credentials.
  2. Server verifies credentials and issues a signed JWT.
  3. Client stores the JWT and sends it with every subsequent request, usually as Authorization: Bearer <token>.
  4. Server verifies the token’s signature and expiration on each request, extracting the user’s permissions directly from the token’s claims.

5. Session-Based Authorization

Common in traditional web apps: after login, the server creates a session and gives the client a session ID (usually via a cookie). The server looks up the session on each request to determine what the user is authorized to do. This works well for browser-based apps but is less common for pure API-to-API communication since it requires server-side session storage.

How Scopes and Permissions Actually Get Enforced

Receiving authorization is only half the story — the API also has to correctly check that authorization on every request. This usually happens through:

  • Scope checking — verifying the token includes the specific scope required for the requested action (e.g., a token with only read:profile can’t call an endpoint requiring write:profile).
  • Role checks — verifying the authenticated user’s role permits the action (admin-only endpoints, for example).
  • Resource ownership checks — verifying the user actually owns or has explicit access to the specific resource they’re requesting, not just that they have the right role in general.

Common Real-World Authorization Patterns

Machine-to-Machine Authorization

When one backend service calls another with no human user involved, OAuth 2.0’s Client Credentials flow is typically used: the calling service authenticates directly with a client ID and secret and receives an access token representing the service itself, not a specific user.

Third-Party App Authorization

This is the classic “Sign in with Google/GitHub/etc.” pattern, using the Authorization Code flow described above, giving users control over exactly what data and actions they’re granting access to.

Mobile and Single-Page App Authorization

Because these apps can’t safely store a client secret, they typically use OAuth 2.0 with PKCE (Proof Key for Code Exchange), which adds an extra layer of protection against intercepted authorization codes.

Best Practices for Handling Received Authorization

  • Store tokens securely. Never put access tokens in local storage in a browser if you can avoid it — prefer secure, HTTP-only cookies where possible, since local storage is more exposed to XSS attacks.
  • Request the minimum scopes you actually need. Don’t ask for full account access if you only need to read a user’s public profile.
  • Handle token expiration gracefully. Implement silent refresh flows so users aren’t constantly forced to log in again.
  • Never log tokens. Access tokens and refresh tokens should never end up in application logs or error tracking tools.
  • Revoke tokens when no longer needed. If a user disconnects a third-party app, make sure the associated tokens are properly invalidated.

Troubleshooting Common Authorization Errors

  • 401 Unauthorized — usually means authentication failed entirely (missing, expired, or invalid token).
  • 403 Forbidden — means you’re authenticated, but you don’t have permission for this specific action or resource.
  • Invalid scope errors — the token you received doesn’t include the permission needed for the endpoint you’re calling; you’ll need to re-request authorization with the correct scope.

Final Thoughts

Receiving authorization in an API context comes down to picking the right mechanism for your situation — API keys for simple server-to-server calls, OAuth 2.0 for delegated third-party access, and JWTs for fast, scalable token verification — and then enforcing those permissions consistently and securely on every single request.

Total
0
Shares

Leave a Reply

Previous Post
How to Describe API Goals with the OpenAPI Specification (OAS): A Complete Beginner-to-Advanced Guide

How to Describe API Goals with the OpenAPI Specification (OAS): A Complete Beginner-to-Advanced Guide

Next Post
Web Application Firewalls for APIs: A Complete Guide to WAF Protection

Web Application Firewalls for APIs: A Complete Guide to WAF Protection

Related Posts