The Social Media Backend secures its endpoints with the OAuth2 password grant flow backed by JSON Web Tokens. A client first exchanges a valid email and password for a short-lived JWT access token; every subsequent request to a protected endpoint must present that token in theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/pvnm4/Social-Media-Backend/llms.txt
Use this file to discover all available pages before exploring further.
Authorization: Bearer <token> HTTP header. The server validates the token on every request without maintaining session state — making the API fully stateless and horizontally scalable.
Token flow
POST credentials to /login
Send the user’s email (as the
username field) and password as application/x-www-form-urlencoded form data to POST /login. No Authorization header is needed for this request.Server verifies credentials and issues a token
The server looks up the user by email, verifies the bcrypt-hashed password, then calls
create_access_token(). The token is signed with the SECRET_KEY environment variable using the ALGORITHM setting (e.g. HS256).Token payload is constructed
The JWT payload contains exactly two claims:
exp is set to utcnow() + ACCESS_TOKEN_EXPIRE_MINUTES and is validated automatically on every decode.Include the token in subsequent requests
Store the returned
access_token and attach it to every protected request as an HTTP header:Server calls get_current_user() on each protected request
FastAPI’s dependency injection calls
get_current_user(), which decodes the JWT with verify_access_token(), extracts user_id, and fetches the corresponding User row from PostgreSQL. The hydrated User object is injected directly into the route handler.Token creation
create_access_token() accepts an arbitrary data dictionary, appends an expiry timestamp, and returns the signed JWT string.
SECRET_KEY, ALGORITHM, and ACCESS_TOKEN_EXPIRE_MINUTES are all loaded from environment variables (or a .env file) via pydantic-settings. See app/config.py for the full Settings model.Token verification
verify_access_token() decodes the raw JWT string and returns a TokenData object containing the user_id. get_current_user() wires this together with a database lookup to produce a fully hydrated User ORM instance.
jwt.InvalidTokenError is caught and a 401 Unauthorized response is returned with a WWW-Authenticate: Bearer header.
Protected vs public endpoints
| Endpoint | Auth Required |
|---|---|
POST /login | No |
POST /users/ | No |
GET /users/{id} | No |
GET /posts/ | Yes |
GET /posts/{id} | Yes |
POST /posts/ | Yes |
PUT /posts/{id} | Yes |
DELETE /posts/{id} | Yes |
POST /vote/ | Yes |
Password hashing
Passwords are never stored in plain text. Before aUser row is inserted into the database the password is hashed with bcrypt via the passlib library. The same context is used to verify a plain-text candidate against the stored hash at login time.
hash() is called during user creation (POST /users/) and the result replaces the raw password before the ORM model is persisted. verify() is called during login to compare the submitted password against the stored hash — bcrypt handles the salt automatically.