Protect Create Expense
Exit

Protect Create Expense

Add authentication to the create expense endpoint

💻

Writing code and entering commands is only available on desktop. Open this page on a larger screen to complete this chapter.

The first endpoint to lock down

With user_id on the model, you can start protecting endpoints. The create_expense endpoint is a natural first choice — every new expense should record who created it.

How the dependency works

You add get_current_user as a parameter to the endpoint function. FastAPI sees it as a dependency and runs it before your endpoint code. If the request has no token or an invalid token, get_current_user raises a 401 error and your endpoint never executes. If the token is valid, FastAPI passes the User object to your function.

The CurrentUser type alias

You will use get_current_user on every expense endpoint. Typing Annotated[User, Depends(get_current_user)] each time is verbose. A type alias called CurrentUser keeps the code clean. Define it once, then use current_user: CurrentUser on every endpoint that needs authentication.

Notice that Depends has been added to the fastapi import in your starter code. You need Depends to wire up the CurrentUser type alias.

Instructions

Protect the create_expense endpoint with token authentication.

  1. Update the auth import to include the verification function: from auth import User, hash_password, verify_password, create_access_token, get_current_user.
  2. Add Annotated to the typing import: from typing import Annotated, Optional — you need this to define the type alias in the next step.
  3. Create a type alias below the imports: CurrentUser = Annotated[User, Depends(get_current_user)]. This tells FastAPI: "whenever an endpoint has a CurrentUser parameter, run get_current_user first and pass me the result." You define it once and reuse it on every protected endpoint.
  4. Add current_user: CurrentUser as a parameter to create_expense, after session: SessionDep. This single parameter does all the work — FastAPI extracts the token from the header, verifies it, looks up the user, and passes the User object to your function. If anything fails, the endpoint never runs.
  5. Before session.add(expense), set the owner: expense.user_id = current_user.id — this stamps the expense with the authenticated user's identifier so you can enforce ownership later.