Step 1 - User Registration & Basic Authentication
Build a simple authentication system using FastAPI, SQLite, and HTTP Basic Authentication. Users can register with a username and password. Passwords are securely hashed before being stored. Public endpoints are accessible by everyone, while protected endpoints require valid username and password credentials.What We Will Build
- Configure a SQLite database.
- Create a
Usermodel.s - Register new users.
- Hash passwords using
bcrypt. - Verify user credentials.
- Implement HTTP Basic Authentication.
- Create public and protected API endpoints.
APIs
Authentication
Protected endpoints use HTTP Basic Authentication. The client sends the username and password in theAuthorization header:
Task 1 - Create the Project
Goal
Create a new FastAPI project for implementing authentication using SQLite and HTTP Basic Authentication.Create the Project
Create the Project Structure
app.py.
- A FastAPI project initialized using
uv. - Required dependencies installed.
- The basic project structure created.
- The application running successfully.
Task 2 - Create the User Model
Goal
Create theUser model to store user credentials and update the application to create the database tables automatically.
Update models.py
Update app.py
Import the User model before creating the database tables.
Why Import User?
Although the User model is not referenced directly, importing it registers the model with SQLModel.metadata. When SQLModel.metadata.create_all(engine) is executed, SQLModel creates the user table in the database.
Run the Application
Verify
After starting the application, a new SQLite database namedauth.db should be created with a user table containing the following columns:
Expected Outcome
At the end of this task, you should have:- A
Usermodel. - A
RegisterRequestmodel. - A
usertable created automatically in the SQLite database. - A FastAPI application ready for implementing user registration.
Task 3 - Implement Password Hashing
Goal
Implement password hashing and verification usingbcrypt.
Update auth.py
Run the File
Expected Output
Why Hash Passwords?
Passwords should never be stored as plain text. Instead, only their hashed values are stored in the database. During authentication, the entered password is hashed and compared with the stored hash.Expected Outcome
At the end of this task, you should have:- A reusable password hashing function.
- A reusable password verification function.
- A simple way to test the implementation independently.
Task 4 - Implement User Registration
Goal
Create an API to register new users by storing their username and hashed password in the database.Update app.py
Run the Application
Test the API
Open the Swagger UI.Verify
Open theuser table in your SQLite database.
The password should be stored as a hashed value similar to:
Expected Outcome
At the end of this task, you should have:- A working user registration API.
- Duplicate username validation.
- Passwords stored securely using hashing.
Task 5 - Implement HTTP Basic Authentication
Goal
Authenticate users using HTTP Basic Authentication by verifying their username and password.Update auth.py
Add the following code.
Nested Dependencies
Theauthenticate_user() function is a dependency that itself depends on two other dependencies.
securityextracts the username and password from theAuthorizationheader.get_session()provides a database session.
Why Does It Work?
Althoughauthenticate_user() is not a route handler, it is executed by FastAPI because it is declared as a dependency using Depends().
FastAPI automatically resolves all nested dependencies before calling the function.
Later, we’ll use it like this:
Important
Depends() works only when FastAPI executes the function.
This works because FastAPI calls authenticate_user() as a dependency.
credentials and session would simply be Depends objects instead of actual values.
Expected Outcome
At the end of this task, you should have:- A reusable authentication dependency.
- Username verification.
- Password verification.
- Proper
401 Unauthorizedresponses for invalid credentials. - An understanding of nested dependency injection in FastAPI.
Task 6 - Create Public and Protected Endpoints
Goal
Create public and protected endpoints to understand how authentication controls access to API resources.Update app.py
Add the following endpoints.
How It Works
The/public endpoint is accessible to everyone.
The /protected endpoint depends on the authenticate_user() dependency. Before executing the endpoint, FastAPI:
- Extracts the username and password from the
Authorizationheader. - Verifies the credentials.
- Returns the authenticated user.
- Executes the endpoint only if authentication succeeds.
Run the Application
Test the APIs
Open the Swagger UI.Public Endpoint
Call:Protected Endpoint
Call:Authentication Flow
Expected Outcome
At the end of this task, you should have:- A public endpoint accessible to everyone.
- A protected endpoint requiring valid credentials.
- A working implementation of HTTP Basic Authentication.