Introduction to Authentication
A real API doesn't hand its data and write paths to anyone who finds the URL. Two related problems show up: knowing who a request is from, and deciding what that person is allowed to do.
Note
That's usually called Authentication vs Authorization
Let's assume our Release Tracker app is made for a company intranet. Anyone can see the Tasks and Projects, but you need to log in to make changes so updates are logged.
Our Release Tracker API only uses the first one, because we're deliberately leaving READs public.
s require a logged-in user. A more elaborate authorization system (per-project roles, owner-only deletes) is out of scope.
Two Practical Approaches
Most API authentication today falls into one of two approaches:
- Single sign-on / OAuth2:
- First-party email + password:
Tip
We're using first-party auth as an example to learn about hashing, tokens, and dependency-based protection.
Rolling your own auth is often a poor choice!
In Production, using API keys, or SSO or other managed identity providers is often a better choice.
What the Flow Looks Like
The release tracker's auth flow has five steps:
-
Registration:
A user is created with an email and a password. The password is hashed before it touches the database.
-
Login:
The client POSTs the email and plain-text password to
/auth/token. -
Verification:
The server looks up the user by email, hashes the submitted password, and compares it against the stored hash.
-
Token issuance:
On a match, the server signs a JSON Web Token (JWT) and sends it back. The token encodes the user's ID and an expiration timestamp.
-
Authenticated requests:
For every protected request after that, the client sends the JWT in the
Authorization: Bearer <token>header. The server verifies the signature, decodes the user ID, and either lets the request through or returns a 401.
FastAPI ships standard tooling for steps 4 and 5: OAuth2PasswordBearer for the security scheme, OAuth2PasswordRequestForm for parsing the login form, and the dependency-injection system for plugging the result into route handlers.