A production-ready JWT authentication system built with FastAPI, featuring secure password hashing, token-based authentication, and industry best practices.
Visit >Tutorial Section< for detailed guide.
- 🔒 JWT-based token authentication
- 🔑 Secure password hashing with bcrypt
- ✅ Input validation with Pydantic
- 📝 Auto-generated API documentation
- ⚙️ Centralized configuration management
- 🏗️ Clean, modular architecture
# Clone and navigate to project
git clone <this-repo-url>
cd fastapi-jwt-auth
# Create virtual environment and install dependencies from the uv.lock file
uv sync
# Generate secret key and configure .env
openssl rand -hex 32 # Copy output to .env as SECRET_KEY
# Run the application
uv run main.pyAccess the API at http://localhost:8000 and interactive docs at http://localhost:8000/docs
Looking for the complete tutorial? Check out Tutorial.md for a comprehensive step-by-step guide covering:
- Detailed setup instructions
- Code explanations and concepts
- Best practices and security considerations
- Testing and deployment guides
- Troubleshooting tips
POST /auth/register- Register new userPOST /auth/login- Login and get JWT token
GET /auth/me- Get current user profileGET /protected- Example protected route
fastapi-jwt-auth/
├── main.py # Application entry point
├── .env # Environment variables
├── core/ # Core functionality (config, security)
├── auth/ # Authentication (models, routes, dependencies)
└── database/ # Data layer
Required variables in .env:
SECRET_KEY=Your_openssl_secret_key
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=20 # (can be changed as per requirement) token will expire after 20 mins from the time when issued
# Application
APP_NAME=FastAPI JWT Authentication TUTORIAL
APP_VERSION=0.1.0
DEBUG=True # set to False for production
# CORS Origins (comma-separated)
# ports depend on the stack trying to access this API usually, React(3000) and Vue(8080)
BACKEND_CORS_ORIGINS=["http://localhost:3000","http://localhost:8080"] Generate a secure SECRET_KEY:
openssl rand -hex 32import requests
# Register
response = requests.post("http://localhost:8000/auth/register", json={
"username": "testuser",
"email": "test@example.com",
"password": "SecurePass123"
})
# Login
response = requests.post("http://localhost:8000/auth/login", data={
"username": "testuser",
"password": "SecurePass123"
})
token = response.json()["access_token"]
# Access protected route
response = requests.get(
"http://localhost:8000/protected",
headers={"Authorization": f"Bearer {token}"}
)- FastAPI - Modern, fast web framework
- Pydantic - Data validation
- python-jose - JWT implementation
- bcrypt - Password hashing
- uvicorn - ASGI server
- JWT Tokens: Stateless authentication with signed tokens
- Password Hashing: Bcrypt for secure password storage
- OAuth2 Flow: Standard password bearer authentication
- Dependency Injection: FastAPI's DI system for reusable auth logic
- Never commit
.envfile to version control - Change
SECRET_KEYbefore production deployment - Use HTTPS in production
- Replace
fake_db.pywith a real database (PostgreSQL, MongoDB, etc.)
- Integrate real database (PostgreSQL/MongoDB)
- Add refresh tokens
- Implement email verification
- Add role-based access control (RBAC)
- Set up CI/CD pipeline
If you find issues or have suggestions for improvements:
- Document the issue clearly
- Provide steps to reproduce
- Suggest a solution if possible
- Test your changes thoroughly
This tutorial is provided as-is for educational purposes.
Built with:
- FastAPI - Modern Python web framework
- Pydantic - Data validation using Python type hints
- python-jose - JWT implementation for Python
- bcrypt - Password hashing
- uvicorn - Lightning-fast ASGI server