Authentication over HTTP

HTTP & the web · Practical · 12 min

Every API you call or build needs authentication, and the HTTP conventions determine how clients and tools handle it.

HTTP has a standard framework for authentication: the client sends Authorization: <scheme> <credentials>, and a server that wants credentials replies 401 Unauthorized with a WWW-Authenticate header naming the scheme it accepts.

Common schemes:

  • Basic: Authorization: Basic base64(user:password). Base64 is encoding, not encryption, so Basic is only acceptable over HTTPS. Still used for simple internal tools and for API key/secret pairs.
  • Bearer: Authorization: Bearer <token>. Whoever holds the token is authenticated. Tokens are often JWTs (signed JSON with claims and an expiry) or opaque random strings checked against a database. OAuth 2.0 access tokens use this scheme.
  • API keys: often in a custom header such as X-API-Key. Avoid putting them in query strings, which end up in logs, browser history and Referer headers.

For browsers, the main alternative is cookie-based sessions: the cookie travels automatically, which is convenient but requires CSRF protection (SameSite, tokens). Bearer tokens sent explicitly by JavaScript don't suffer from CSRF but must be stored somewhere scripts can read, exposing them to XSS.

Status codes: 401 means "who are you?" (missing, invalid or expired credentials; the client should log in or refresh a token). 403 means "I know who you are, and no". Rate-limited clients get 429.

Always use HTTPS, give tokens short lifetimes, and never log Authorization headers.

Example

# Basic auth: curl encodes user:password for you
$ curl -u ada:s3cret https://api.example.com/me
# sends: Authorization: Basic YWRhOnMzY3JldA==
$ echo -n 'ada:s3cret' | base64
YWRhOnMzY3JldA==

# Bearer token
$ curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI0MiJ9.sig" \
       https://api.example.com/me

# A server demanding credentials
$ curl -si https://api.example.com/me | head -3
HTTP/2 401
www-authenticate: Bearer realm="api", error="invalid_token"
content-type: application/json

Remember

  • Authorization: <scheme> <credentials>; 401 + WWW-Authenticate asks for them
  • Basic is base64, not encryption: HTTPS only
  • Bearer tokens authenticate whoever holds them
  • 401 = not authenticated, 403 = not permitted

Watch out for

  • Passing API keys in the URL query string, where they leak into logs and Referer headers.

Check yourself

  1. What does the Basic credential 'YWRhOnMzY3JldA==' protect against on plain HTTP?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Authentication

Builds on

Unlocks

Nothing builds on this yet.