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.
- Update the auth import to include the verification function:
from auth import User, hash_password, verify_password, create_access_token, get_current_user. - Add
Annotatedto the typing import:from typing import Annotated, Optional— you need this to define the type alias in the next step. - Create a type alias below the imports:
CurrentUser = Annotated[User, Depends(get_current_user)]. This tells FastAPI: "whenever an endpoint has aCurrentUserparameter, runget_current_userfirst and pass me the result." You define it once and reuse it on every protected endpoint. - Add
current_user: CurrentUseras a parameter tocreate_expense, aftersession: SessionDep. This single parameter does all the work — FastAPI extracts the token from the header, verifies it, looks up the user, and passes theUserobject to your function. If anything fails, the endpoint never runs. - 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.
Interactive Code Editor
Sign in to write and run code, track your progress, and unlock all chapters.
Sign In to Start Coding