Skip to content

Commit e51c715

Browse files
committed
Add README.md for Authentication API documentation
- Introduced a comprehensive README.md detailing the features, setup instructions, and API endpoints for the FastAPI-based authentication system with Firebase integration. - Added project structure overview, environment variable configuration, and security considerations. - Included examples for user registration, login, and protected routes. - Updated requirements.txt to include firebase-admin and PyJWT for authentication functionality. - Created example protected routes in app/example_protected_routes.py to demonstrate role-based access control and user authentication. - Added test_auth.py as a placeholder for future tests.
1 parent d380785 commit e51c715

File tree

5 files changed

+367
-1
lines changed

5 files changed

+367
-1
lines changed

README.md

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
# Authentication API with Firebase
2+
3+
A FastAPI-based authentication system with Firebase integration, providing user registration, login, and token-based authentication.
4+
5+
## Features
6+
7+
- 🔐 Firebase Authentication integration
8+
- 📝 User registration and login
9+
- 🔑 JWT token-based authentication
10+
- 🔄 Token refresh functionality
11+
- 🛡️ Role-based access control
12+
- 📚 Auto-generated API documentation
13+
- 🌐 CORS support
14+
15+
## Project Structure
16+
17+
```
18+
├── app/
19+
│ ├── __init__.py
20+
│ ├── main.py # FastAPI application
21+
│ └── auth/
22+
│ ├── __init__.py
23+
│ ├── models.py # Pydantic models
24+
│ ├── firebase_auth.py # Firebase authentication service
25+
│ ├── dependencies.py # Authentication dependencies
26+
│ └── routes.py # API routes
27+
├── run.py # Application entry point
28+
├── requirements.txt # Python dependencies
29+
├── env.example # Environment variables template
30+
└── README.md # This file
31+
```
32+
33+
## Setup
34+
35+
### 1. Install Dependencies
36+
37+
```bash
38+
pip install -r requirements.txt
39+
```
40+
41+
### 2. Firebase Configuration
42+
43+
1. Create a Firebase project at [Firebase Console](https://console.firebase.google.com/)
44+
2. Enable Authentication in your Firebase project
45+
3. Create a service account:
46+
- Go to Project Settings > Service Accounts
47+
- Click "Generate new private key"
48+
- Download the JSON file
49+
50+
### 3. Environment Variables
51+
52+
Copy `env.example` to `.env` and configure the variables:
53+
54+
```bash
55+
cp env.example .env
56+
```
57+
58+
Required environment variables:
59+
60+
```env
61+
# Firebase Configuration (choose one option)
62+
# Option 1: Firebase credentials as JSON string
63+
FIREBASE_CREDENTIALS={"type":"service_account","project_id":"your-project-id",...}
64+
65+
# Option 2: Path to Firebase service account JSON file
66+
FIREBASE_SERVICE_ACCOUNT_PATH=./firebase-service-account.json
67+
68+
# JWT Configuration
69+
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
70+
71+
# Application Configuration
72+
ENVIRONMENT=development
73+
DEBUG=true
74+
LOG_LEVEL=info
75+
76+
# Server Configuration
77+
HOST=0.0.0.0
78+
PORT=8000
79+
80+
# CORS Configuration
81+
ALLOWED_ORIGINS=http://localhost:3000,http://localhost:8080
82+
```
83+
84+
### 4. Run the Application
85+
86+
```bash
87+
python run.py
88+
```
89+
90+
The API will be available at:
91+
- API: http://localhost:8000
92+
- Documentation: http://localhost:8000/docs
93+
- ReDoc: http://localhost:8000/redoc
94+
95+
## API Endpoints
96+
97+
### Authentication Endpoints
98+
99+
| Method | Endpoint | Description |
100+
|--------|----------|-------------|
101+
| POST | `/auth/signup` | Register a new user |
102+
| POST | `/auth/login` | Login user |
103+
| POST | `/auth/refresh` | Refresh access token |
104+
| GET | `/auth/me` | Get current user info |
105+
| POST | `/auth/logout` | Logout user |
106+
| GET | `/auth/verify` | Verify token validity |
107+
108+
### Request/Response Examples
109+
110+
#### User Registration
111+
112+
```bash
113+
POST /auth/signup
114+
Content-Type: application/json
115+
116+
{
117+
"email": "[email protected]",
118+
"password": "securepassword123",
119+
"first_name": "John",
120+
"last_name": "Doe"
121+
}
122+
```
123+
124+
Response:
125+
```json
126+
{
127+
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
128+
"refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
129+
"token_type": "bearer",
130+
"user": {
131+
"id": "firebase-user-id",
132+
"email": "[email protected]",
133+
"first_name": "John",
134+
"last_name": "Doe",
135+
"is_active": true,
136+
"created_at": "2024-01-01T00:00:00Z"
137+
}
138+
}
139+
```
140+
141+
#### User Login
142+
143+
```bash
144+
POST /auth/login
145+
Content-Type: application/json
146+
147+
{
148+
"email": "[email protected]",
149+
"password": "securepassword123"
150+
}
151+
```
152+
153+
#### Token Refresh
154+
155+
```bash
156+
POST /auth/refresh
157+
Content-Type: application/json
158+
159+
{
160+
"refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
161+
}
162+
```
163+
164+
#### Protected Endpoint Example
165+
166+
```bash
167+
GET /auth/me
168+
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
169+
```
170+
171+
## Authentication Dependencies
172+
173+
The authentication system provides several dependency functions for protecting routes:
174+
175+
### Basic Authentication
176+
177+
```python
178+
from app.auth.dependencies import get_current_user
179+
180+
@app.get("/protected")
181+
async def protected_route(current_user = Depends(get_current_user)):
182+
return {"message": f"Hello {current_user['email']}"}
183+
```
184+
185+
### Active User Check
186+
187+
```python
188+
from app.auth.dependencies import get_current_active_user
189+
190+
@app.get("/active-only")
191+
async def active_user_route(current_user = Depends(get_current_active_user)):
192+
return {"message": "Active user only"}
193+
```
194+
195+
### Role-Based Access
196+
197+
```python
198+
from app.auth.dependencies import require_admin, require_user
199+
200+
@app.get("/admin-only")
201+
async def admin_route(current_user = Depends(require_admin)):
202+
return {"message": "Admin only"}
203+
204+
@app.get("/user-route")
205+
async def user_route(current_user = Depends(require_user)):
206+
return {"message": "User or admin"}
207+
```
208+
209+
## Error Handling
210+
211+
The API returns appropriate HTTP status codes and error messages:
212+
213+
- `400 Bad Request`: Invalid request data
214+
- `401 Unauthorized`: Invalid or missing authentication
215+
- `403 Forbidden`: Insufficient permissions
216+
- `500 Internal Server Error`: Server-side errors
217+
218+
## Security Considerations
219+
220+
1. **JWT Secret**: Use a strong, unique secret key in production
221+
2. **Firebase Credentials**: Keep service account credentials secure
222+
3. **CORS**: Configure allowed origins properly for production
223+
4. **Password Policy**: Implement strong password requirements
224+
5. **Rate Limiting**: Consider adding rate limiting for auth endpoints
225+
6. **HTTPS**: Always use HTTPS in production
226+
227+
## Development
228+
229+
### Running in Development Mode
230+
231+
```bash
232+
python run.py
233+
```
234+
235+
The server will run with auto-reload enabled.
236+
237+
### Testing
238+
239+
You can test the API using the interactive documentation at http://localhost:8000/docs
240+
241+
### Environment Variables for Development
242+
243+
For development, you can use the default values in `env.example`. Make sure to:
244+
245+
1. Set up a Firebase project
246+
2. Configure the Firebase credentials
247+
3. Generate a secure JWT secret
248+
249+
## Production Deployment
250+
251+
1. Set `ENVIRONMENT=production`
252+
2. Configure proper CORS origins
253+
3. Use environment-specific Firebase credentials
254+
4. Set up proper logging
255+
5. Use a production WSGI server like Gunicorn
256+
6. Configure reverse proxy (nginx)
257+
7. Set up SSL/TLS certificates
258+
259+
## Contributing
260+
261+
1. Fork the repository
262+
2. Create a feature branch
263+
3. Make your changes
264+
4. Add tests if applicable
265+
5. Submit a pull request
266+
267+
## License
268+
269+
This project is licensed under the MIT License.

app/example_protected_routes.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
from fastapi import APIRouter, Depends
2+
from app.auth.dependencies import get_current_user, get_current_active_user, require_admin, require_user
3+
from typing import Dict, Any
4+
5+
router = APIRouter(prefix="/protected", tags=["protected"])
6+
7+
8+
@router.get("/user-info")
9+
async def get_user_info(current_user: Dict[str, Any] = Depends(get_current_user)):
10+
"""
11+
Get information about the currently authenticated user
12+
"""
13+
return {
14+
"message": "User information retrieved successfully",
15+
"user": {
16+
"id": current_user["uid"],
17+
"email": current_user["email"],
18+
"first_name": current_user["first_name"],
19+
"last_name": current_user["last_name"],
20+
"role": current_user["role"]
21+
}
22+
}
23+
24+
25+
@router.get("/active-only")
26+
async def active_users_only(current_user: Dict[str, Any] = Depends(get_current_active_user)):
27+
"""
28+
Endpoint that only allows active users
29+
"""
30+
return {
31+
"message": "This endpoint is only accessible to active users",
32+
"user_email": current_user["email"]
33+
}
34+
35+
36+
@router.get("/admin-only")
37+
async def admin_only(current_user: Dict[str, Any] = Depends(require_admin)):
38+
"""
39+
Endpoint that only allows admin users
40+
"""
41+
return {
42+
"message": "This endpoint is only accessible to admin users",
43+
"admin_email": current_user["email"]
44+
}
45+
46+
47+
@router.get("/user-or-admin")
48+
async def user_or_admin(current_user: Dict[str, Any] = Depends(require_user)):
49+
"""
50+
Endpoint that allows both regular users and admins
51+
"""
52+
return {
53+
"message": "This endpoint is accessible to users and admins",
54+
"user_email": current_user["email"],
55+
"user_role": current_user["role"]
56+
}
57+
58+
59+
@router.post("/create-resource")
60+
async def create_resource(
61+
resource_data: dict,
62+
current_user: Dict[str, Any] = Depends(get_current_active_user)
63+
):
64+
"""
65+
Example of creating a resource with user authentication
66+
"""
67+
return {
68+
"message": "Resource created successfully",
69+
"resource": resource_data,
70+
"created_by": current_user["email"],
71+
"user_id": current_user["uid"]
72+
}
73+
74+
75+
@router.delete("/delete-resource/{resource_id}")
76+
async def delete_resource(
77+
resource_id: str,
78+
current_user: Dict[str, Any] = Depends(require_admin)
79+
):
80+
"""
81+
Example of deleting a resource (admin only)
82+
"""
83+
return {
84+
"message": f"Resource {resource_id} deleted successfully",
85+
"deleted_by": current_user["email"]
86+
}

app/main.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from fastapi.middleware.cors import CORSMiddleware
33
from fastapi.responses import JSONResponse
44
from .auth.routes import router as auth_router
5+
from .example_protected_routes import router as protected_router
56
import os
67

78
# Create FastAPI app
@@ -23,6 +24,9 @@
2324
# Include authentication routes
2425
app.include_router(auth_router)
2526

27+
# Include protected routes (examples)
28+
app.include_router(protected_router)
29+
2630
# Global exception handler
2731
@app.exception_handler(Exception)
2832
async def global_exception_handler(request, exc):
@@ -42,5 +46,9 @@ async def root():
4246
return {
4347
"message": "Welcome to Authentication API",
4448
"docs": "/docs",
45-
"redoc": "/redoc"
49+
"redoc": "/redoc",
50+
"endpoints": {
51+
"auth": "/auth",
52+
"protected": "/protected"
53+
}
4654
}

0 commit comments

Comments
 (0)