ft_transcendence_backend is the backend for a full-stack project that uses 2FA-secured authentication with JWT. It is built with Django and Django REST Framework (DRF) and uses PostgreSQL as the database. Communication with the frontend occurs via a REST API.
git clone https://github.com/your-repo/ft_transcendence_backend.git
cd ft_transcendence_backend
python3 -m venv venv
source venv/bin/activate # (Windows: venv\Scripts\activate)
pip install -r requirements.txt
.env
File)Create a .env
file in the backend/
directory and add the following values:
POSTGRES_DB=transcendence
POSTGRES_USER=user
POSTGRES_PASSWORD=pass
SECRET_KEY=your-secret-key
DEBUG=True
ALLOWED_HOSTS=*
python manage.py migrate
python manage.py createsuperuser # If an admin login is needed
python manage.py runserver 0.0.0.0:8000
All API endpoints are located under /api/users/
.
POST /api/users/register/
{
"username": "testuser",
"email": "test@example.com",
"password": "securepassword"
}
Response:
{
"id": 1,
"username": "testuser",
"email": "test@example.com"
}
POST /api/users/login/
{
"username": "testuser",
"password": "securepassword"
}
Response:
{
"refresh": "eyJhbGciOiJIUzI1NiIsInR5c...",
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6..."
}
POST /api/users/verify/send/
{
"email": "test@example.com"
}
Response:
{
"message": "Verification code sent."
}
POST /api/users/verify/
{
"email": "test@example.com",
"code": "123456"
}
Response:
{
"message": "User verified."
}
users.models.CustomUser
)class CustomUser(AbstractUser):
email = models.EmailField(unique=True)
avatar = models.ImageField(upload_to='avatars/', null=True, blank=True)
bio = models.TextField(null=True, blank=True)
verification_code = models.CharField(max_length=6, blank=True, null=True)
is_verified = models.BooleanField(default=False)
If changes are made to the models:
python manage.py makemigrations
python manage.py migrate
If you want to use Docker, you can start the backend with docker-compose
.
docker-compose up --build
To restart only the backend:
docker-compose restart backend
Stop containers:
docker-compose down
View logs:
docker-compose logs -f
curl -X POST http://127.0.0.1:8000/api/users/register/ \
-H "Content-Type: application/json" \
-d '{"username": "testuser", "email": "test@example.com", "password": "securepassword"}'
curl -X POST http://127.0.0.1:8000/api/users/login/ \
-H "Content-Type: application/json" \
-d '{"username": "testuser", "password": "securepassword"}'
curl -X POST http://127.0.0.1:8000/api/users/verify/send/ \
-H "Content-Type: application/json" \
-d '{"email": "test@example.com"}'
curl -X POST http://127.0.0.1:8000/api/users/verify/ \
-H "Content-Type: application/json" \
-d '{"email": "test@example.com", "code": "123456"}'
This documentation provides an overview of:
β
Installation & Setup
β
API Endpoints
β
Authentication with JWT & 2FA
β
Database Models & Migrations
β
Docker & Deployment
β
Example Requests with cURL
If you need further additions, let me know! π
graph TD;
subgraph "π Transcendence Backend System"
subgraph "π₯ Redis (Cache & Message Broker)"
R1["β
Fast Storage"]
R2["π Communication with Django"]
R3["π Session Storage"]
end
subgraph "π PostgreSQL (Database)"
DB1["π¦ Stores User & Game Data"]
DB2["π Queries & Transactions"]
DB3["π Uses Healthcheck for Availability"]
end
subgraph "π Django Backend (REST API)"
D1["π‘ Provides API for Frontend"]
D2["π Authentication (JWT & 2FA)"]
D3["π Database Interaction"]
D4["π Caching & Sessions via Redis"]
end
subgraph "π Nginx Reverse Proxy"
N1["π Forwards Requests to Django"]
N2["π₯οΈ Serves Static Frontend"]
N3["π Can Handle SSL Termination"]
end
end
%% Connections between services
R1 -.-> D4;
R2 -.-> D4;
DB1 --> D3;
DB2 --> D3;
DB3 -->|Healthcheck: Is DB reachable?| D3;
D1 --> N1;
D2 -->|Authentication via API| N1;
N1 -->|API Access & Static Files| Browser["π₯οΈ Web Browser"];
%% Visual Styling
classDef service fill:#f9f,stroke:#333,stroke-width:2px;
classDef database fill:#ffd700,stroke:#333,stroke-width:2px;
classDef cache fill:#ff6961,stroke:#333,stroke-width:2px;
classDef proxy fill:#61affe,stroke:#333,stroke-width:2px;
classDef frontend fill:#85C1E9,stroke:#333,stroke-width:2px;
class Redis cache;
class PostgreSQL database;
class Django service;
class Nginx proxy;
class Browser frontend;
For Django, you should configure logging to output to both stdout (console) and GELF (Logstash). Hereβs how to set it up properly:
LOGGING
Configuration (stdout + GELF)LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
'style': '{',
},
'json': {
'()': 'pythonjsonlogger.jsonlogger.JsonFormatter',
'format': '''
%(asctime)s %(levelname)s %(name)s
%(module)s %(process)d %(thread)d %(message)s
''',
},
},
'handlers': {
'console': {
'level': 'INFO',
'class': 'logging.StreamHandler',
'formatter': 'verbose',
},
'gelf': {
'class': 'pygelf.GelfUdpHandler', # UDP is faster than TCP for logs
'host': 'logstash', # Docker service name
'port': 12201, # Default GELF UDP port
'formatter': 'json', # JSON format for Logstash
'include_extra_fields': True, # Optional: Adds Django request metadata
'compress': True, # Optional: Compress logs for better performance
},
},
'loggers': {
'django': {
'handlers': ['console', 'gelf'],
'level': 'INFO',
'propagate': False,
},
# Custom app loggers (if needed)
'myapp': {
'handlers': ['console', 'gelf'],
'level': 'DEBUG',
'propagate': False,
},
},
'root': {
'handlers': ['console', 'gelf'],
'level': 'INFO',
},
}
StreamHandler
(console
)
docker compose logs
).verbose
format.pygelf.GelfUdpHandler
)
propagate=False
pygelf
& python-json-logger
pip install pygelf python-json-logger
logstash.conf
)input {
gelf {
port => 12201
type => "gelf"
}
}
docker-compose.yml
services:
logstash:
ports:
- "12201:12201/udp" # GELF UDP port
docker compose logs backend
Should show human-readable logs.
docker compose logs logstash
'gelf': {
'class': 'pygelf.GelfUdpHandler',
'host': 'logstash',
'port': 12201,
'include_extra_fields': True, # Adds Django request info (user, IP, etc.)
}
'class': 'pygelf.GelfTcpHandler',
'file': {
'class': 'logging.handlers.RotatingFileHandler',
'filename': '/app/logs/django.log',
'maxBytes': 5 * 1024 * 1024, # 5MB
'backupCount': 3,
}
logstash
) for networking.verbose
for humans.This setup gives you real-time stdout logs (for debugging) + centralized GELF logs (for analysis in Logstash/Elasticsearch/Kibana). π