Back to HTTP Headers

Authorization auth request

Carries the client's credentials to authenticate with the server — the most fundamental header in HTTP authentication.

What it does

Authorization carries the client's credentials on a request. The server checks these credentials and either grants access or returns 401 Unauthorized. It's the core mechanism behind HTTP authentication — whether you're sending a username/password, an API key, or a JWT token.

The header always starts with an authentication scheme that tells the server how to interpret the credentials that follow.

Syntax

Authorization: <scheme> <credentials>

Examples:

Authorization: Basic dXNlcjpwYXNzd29yZA==
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Authorization: Digest username="user", realm="example.com", ...
Authorization: ApiKey sk-prod-abc123xyz

Authentication schemes

Basic

Authorization: Basic <base64(username:password)>

Encodes username:password as Base64 and sends it. Simple but critically not encrypted — Base64 is trivially reversible. Only use Basic auth over HTTPS, never HTTP.

// Generating Basic auth credentials
const credentials = btoa('username:password');
// Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

Bearer

Authorization: Bearer <token>

The most common scheme in modern APIs. The token is typically a JWT (JSON Web Token) issued after login, but it can be any opaque token your server understands. "Bearer" means "whoever has this token gets access" — so keep tokens short-lived and treat them like passwords.

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0In0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Digest

Authorization: Digest username="user", realm="example.com", nonce="abc", uri="/", response="hash"

A challenge-response scheme that avoids sending the password directly. More secure than Basic but complex to implement and rarely used in new systems. OAuth/Bearer has largely replaced it.

API Key (non-standard)

Many APIs use Authorization for API keys even though there's no formal scheme for it:

Authorization: ApiKey sk-prod-abc123xyz
Authorization: Token myapikey123
Authorization: Key abc123

These are valid HTTP headers but non-standard schemes — the server defines how to parse them. Some APIs prefer a custom header (X-API-Key) instead.

The authentication flow

Authorization works in tandem with WWW-Authenticate:

  1. Client makes a request without credentials
  2. Server returns 401 Unauthorized with WWW-Authenticate: Bearer realm="api" (telling the client what scheme to use)
  3. Client sends the request again with Authorization: Bearer <token>
  4. Server validates and responds with 200 OK (or 403 Forbidden if credentials are valid but access is denied)

Many clients (especially API clients with pre-configured tokens) skip step 1-2 and send Authorization on the first request.

Preemptive vs reactive auth

Reactive: Client waits for a 401, then retries with credentials. Adds a round trip but avoids sending credentials unnecessarily.

Preemptive: Client sends Authorization on every request from the start. Common for API clients where credentials are always required. Saves the 401 round trip.

Security considerations

Always use HTTPS. Authorization credentials are in plain text in the HTTP header (Base64 is not encryption). Any network observer can read them. HTTPS is non-negotiable.

Cache-Control implications. By default, responses to requests with Authorization are treated as private and not stored by shared caches — even without Cache-Control: private. If you want a CDN to cache authenticated responses, you must explicitly add Cache-Control: public or s-maxage.

Token expiry. Bearer tokens should be short-lived. A stolen long-lived token is compromised until it expires. Use refresh tokens for long sessions.

Don't log the Authorization header. Access logs that include request headers will capture tokens and passwords verbatim. Scrub Authorization from logs.

Common mistakes and gotchas

Sending Basic auth over HTTP. Base64 is reversible in milliseconds. Over HTTP, anyone on the network can decode the credentials instantly. HTTPS only.

Storing Bearer tokens in localStorage. Tokens in localStorage are accessible to any JavaScript on the page — including third-party scripts and XSS payloads. Use httpOnly cookies for sensitive tokens, or at minimum be aware of the XSS risk.

Confusing 401 and 403. 401 Unauthorized means "you haven't authenticated" — credentials are missing or invalid. 403 Forbidden means "you've authenticated but you don't have permission." These are commonly misused.

Not stripping Authorization on redirects. By default, browsers strip the Authorization header when following a redirect to a different origin. This is correct security behaviour — don't fight it. If your API redirects authenticated requests, reconsider the design.

Real-world examples

Bearer token (JWT):

GET /api/profile HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI0MiJ9.abc123

Basic auth:

GET /admin HTTP/1.1
Authorization: Basic c2FpbmVzaDpodW50ZXIy

API key:

POST /api/send-email HTTP/1.1
Authorization: Bearer sk-prod-abc123xyz456
Content-Type: application/json

Full 401 → retry flow:

GET /api/secret HTTP/1.1

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="api", error="unauthorized"

GET /api/secret HTTP/1.1
Authorization: Bearer mytoken123

HTTP/1.1 200 OK

FAQ

What's the difference between Authorization and authentication?

Authentication is the process; Authorization is the HTTP header that carries the credentials for that process. Confusingly, HTTP's Authorization header is used for authentication (proving who you are), not authorization (deciding what you can do) — the naming is a historical accident from HTTP/1.0.

Should I use Authorization or a custom header like X-API-Key?

Both work. Authorization with a scheme is more standards-compliant and understood by HTTP tooling (proxies, API gateways, monitoring). Custom headers like X-API-Key are explicit and easy to parse. The main practical difference: Authorization is automatically stripped by browsers on cross-origin redirects; custom headers are not. For most APIs, Authorization: ApiKey ... or Authorization: Bearer ... is the cleaner choice.

Can Authorization be used with GET requests?

Yes. It's a request header — it works on any HTTP method. GET requests can and do carry Authorization, especially for authenticated read-only API endpoints.

Is Bearer always a JWT?

No. "Bearer" just means "whoever bears this token gets access." The token can be a JWT, an opaque random string, a session identifier, or anything else your server issues and validates. JWT is the most common format, but the scheme doesn't mandate it.

Fun fact

The name "Authorization" header is one of HTTP's most enduring naming confusions. In security, "authentication" means proving who you are, while "authorization" means deciding what you're allowed to do. The Authorization header carries authentication credentials — it proves identity. The actual authorization (access control) happens on the server after the credentials are validated. Roy Fielding, one of HTTP's primary authors, has acknowledged this naming was a mistake, but it's now baked into every HTTP implementation ever written.