fixes
This commit is contained in:
parent
7e5e390eb0
commit
f54ead4334
|
|
@ -0,0 +1,31 @@
|
|||
# Сервер
|
||||
SERVER_IP=192.168.1.8
|
||||
# Для домена замените на:
|
||||
# SERVER_IP=yourdomain.com
|
||||
# FRONTEND_URL=https://yourdomain.com
|
||||
# BACKEND_URL=https://api.yourdomain.com
|
||||
|
||||
# Порты
|
||||
FRONTEND_PORT=8095
|
||||
BACKEND_PORT=8094
|
||||
MINIO_API_PORT=9090
|
||||
MINIO_CONSOLE_PORT=9091
|
||||
REDIS_PORT=6388
|
||||
|
||||
# S3 Storage
|
||||
S3_DATA_PATH=/mnt/data/s3
|
||||
|
||||
# Безопасность (ОБЯЗАТЕЛЬНО ПОМЕНЯЙТЕ В PRODUCTION!)
|
||||
JWT_SECRET=dev-secret-key-change-in-production
|
||||
MINIO_ROOT_USER=minioadmin
|
||||
MINIO_ROOT_PASSWORD=minioadmin
|
||||
|
||||
# CORS Origins (добавьте свой домен)
|
||||
# Для production:
|
||||
# CORS_ORIGINS=https://yourdomain.com,https://www.yourdomain.com
|
||||
CORS_ORIGINS=http://${SERVER_IP}:${FRONTEND_PORT},http://localhost:${FRONTEND_PORT}
|
||||
|
||||
# API URL для frontend
|
||||
# Для production:
|
||||
# VITE_API_URL=https://api.yourdomain.com
|
||||
VITE_API_URL=http://${SERVER_IP}:${BACKEND_PORT}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
# Инструкция по развертыванию
|
||||
|
||||
## Текущая конфигурация (разработка)
|
||||
|
||||
Сейчас проект настроен для локальной сети на IP `192.168.1.8`:
|
||||
- Frontend: http://192.168.1.8:8095
|
||||
- Backend: http://192.168.1.8:8094
|
||||
- MinIO Console: http://192.168.1.8:9091
|
||||
|
||||
## Переход на домен (production)
|
||||
|
||||
Когда будете ставить на домен, просто отредактируйте файл `.env`:
|
||||
|
||||
### Вариант 1: Домен без поддомена
|
||||
|
||||
```bash
|
||||
# .env
|
||||
SERVER_IP=yourdomain.com
|
||||
CORS_ORIGINS=https://yourdomain.com,https://www.yourdomain.com
|
||||
VITE_API_URL=https://yourdomain.com:8094
|
||||
|
||||
# Рекомендуется сменить порты на стандартные через nginx:
|
||||
# FRONTEND_PORT=80 (или 443 для HTTPS)
|
||||
# BACKEND_PORT=8080 (скрыть за nginx reverse proxy)
|
||||
```
|
||||
|
||||
### Вариант 2: С поддоменом для API (рекомендуется)
|
||||
|
||||
```bash
|
||||
# .env
|
||||
SERVER_IP=yourdomain.com
|
||||
CORS_ORIGINS=https://yourdomain.com,https://www.yourdomain.com,https://api.yourdomain.com
|
||||
VITE_API_URL=https://api.yourdomain.com
|
||||
|
||||
# Настроить nginx reverse proxy:
|
||||
# yourdomain.com -> frontend:8095
|
||||
# api.yourdomain.com -> backend:8094
|
||||
```
|
||||
|
||||
### Обязательно измените в production:
|
||||
|
||||
```bash
|
||||
JWT_SECRET=ваш-очень-длинный-случайный-секретный-ключ
|
||||
MINIO_ROOT_USER=ваш-логин
|
||||
MINIO_ROOT_PASSWORD=ваш-сильный-пароль
|
||||
```
|
||||
|
||||
## Настройка HTTPS (nginx + Let's Encrypt)
|
||||
|
||||
Создайте `nginx.conf`:
|
||||
|
||||
```nginx
|
||||
# Frontend
|
||||
server {
|
||||
listen 80;
|
||||
server_name yourdomain.com www.yourdomain.com;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:8095;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
}
|
||||
|
||||
# Backend API
|
||||
server {
|
||||
listen 80;
|
||||
server_name api.yourdomain.com;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:8094;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Затем установите SSL сертификаты:
|
||||
|
||||
```bash
|
||||
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com -d api.yourdomain.com
|
||||
```
|
||||
|
||||
## Быстрая смена конфигурации
|
||||
|
||||
1. Отредактируйте `.env`
|
||||
2. Перезапустите контейнеры:
|
||||
```bash
|
||||
docker-compose down
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
Готово! 🚀
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
"""Security utilities for authentication and authorization."""
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
import hashlib
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from typing import Optional
|
||||
|
||||
from jose import JWTError, jwt
|
||||
|
|
@ -16,15 +17,22 @@ pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
|||
|
||||
def hash_password(password: str) -> str:
|
||||
"""
|
||||
Hash a password using bcrypt.
|
||||
Hash a password using bcrypt with SHA256 pre-hashing.
|
||||
|
||||
Args:
|
||||
password: Plain text password
|
||||
password: Plain text password (any length supported)
|
||||
|
||||
Returns:
|
||||
Hashed password
|
||||
|
||||
Note:
|
||||
Uses SHA256 pre-hashing to support passwords of any length,
|
||||
avoiding bcrypt's 72-byte limitation.
|
||||
"""
|
||||
return pwd_context.hash(password)
|
||||
# Pre-hash with SHA256 to support unlimited password length
|
||||
# This is a common technique to work around bcrypt's 72-byte limit
|
||||
password_hash = hashlib.sha256(password.encode('utf-8')).hexdigest()
|
||||
return pwd_context.hash(password_hash)
|
||||
|
||||
|
||||
def verify_password(plain_password: str, hashed_password: str) -> bool:
|
||||
|
|
@ -38,7 +46,9 @@ def verify_password(plain_password: str, hashed_password: str) -> bool:
|
|||
Returns:
|
||||
True if password matches, False otherwise
|
||||
"""
|
||||
return pwd_context.verify(plain_password, hashed_password)
|
||||
# Apply same SHA256 pre-hashing as hash_password
|
||||
password_hash = hashlib.sha256(plain_password.encode('utf-8')).hexdigest()
|
||||
return pwd_context.verify(password_hash, hashed_password)
|
||||
|
||||
|
||||
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -> str:
|
||||
|
|
@ -54,9 +64,9 @@ def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -
|
|||
"""
|
||||
to_encode = data.copy()
|
||||
if expires_delta:
|
||||
expire = datetime.utcnow() + expires_delta
|
||||
expire = datetime.now(timezone.utc) + expires_delta
|
||||
else:
|
||||
expire = datetime.utcnow() + timedelta(seconds=settings.jwt_access_ttl_seconds)
|
||||
expire = datetime.now(timezone.utc) + timedelta(seconds=settings.jwt_access_ttl_seconds)
|
||||
|
||||
to_encode.update({"exp": expire, "type": "access"})
|
||||
encoded_jwt = jwt.encode(to_encode, settings.jwt_secret, algorithm=settings.jwt_algorithm)
|
||||
|
|
@ -74,7 +84,7 @@ def create_refresh_token(data: dict) -> str:
|
|||
Encoded JWT token
|
||||
"""
|
||||
to_encode = data.copy()
|
||||
expire = datetime.utcnow() + timedelta(seconds=settings.jwt_refresh_ttl_seconds)
|
||||
expire = datetime.now(timezone.utc) + timedelta(seconds=settings.jwt_refresh_ttl_seconds)
|
||||
to_encode.update({"exp": expire, "type": "refresh"})
|
||||
encoded_jwt = jwt.encode(to_encode, settings.jwt_secret, algorithm=settings.jwt_algorithm)
|
||||
return encoded_jwt
|
||||
|
|
|
|||
|
|
@ -4,17 +4,17 @@ services:
|
|||
backend:
|
||||
build: ./backend
|
||||
ports:
|
||||
- "8094:8000"
|
||||
- "${BACKEND_PORT:-8094}:8000"
|
||||
environment:
|
||||
- APP_ENV=dev
|
||||
- DATABASE_URL=sqlite+aiosqlite:////app/data/app.db
|
||||
- S3_ENDPOINT_URL=http://minio:9000
|
||||
- S3_REGION=us-east-1
|
||||
- S3_ACCESS_KEY_ID=minioadmin
|
||||
- S3_SECRET_ACCESS_KEY=minioadmin
|
||||
- S3_ACCESS_KEY_ID=${MINIO_ROOT_USER:-minioadmin}
|
||||
- S3_SECRET_ACCESS_KEY=${MINIO_ROOT_PASSWORD:-minioadmin}
|
||||
- MEDIA_BUCKET=itcloud-media
|
||||
- JWT_SECRET=dev-secret-key-change-in-production
|
||||
- CORS_ORIGINS=http://192.168.1.8:8095,http://localhost:8095,http://localhost:3000
|
||||
- JWT_SECRET=${JWT_SECRET:-dev-secret-key-change-in-production}
|
||||
- CORS_ORIGINS=${CORS_ORIGINS}
|
||||
- REDIS_URL=redis://redis:6379/0
|
||||
volumes:
|
||||
- ./backend/src:/app/src
|
||||
|
|
@ -27,13 +27,13 @@ services:
|
|||
minio:
|
||||
image: minio/minio:latest
|
||||
ports:
|
||||
- "9090:9000"
|
||||
- "9091:9001"
|
||||
- "${MINIO_API_PORT:-9090}:9000"
|
||||
- "${MINIO_CONSOLE_PORT:-9091}:9001"
|
||||
environment:
|
||||
- MINIO_ROOT_USER=minioadmin
|
||||
- MINIO_ROOT_PASSWORD=minioadmin
|
||||
- MINIO_ROOT_USER=${MINIO_ROOT_USER:-minioadmin}
|
||||
- MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD:-minioadmin}
|
||||
volumes:
|
||||
- /mnt/data/s3:/data
|
||||
- ${S3_DATA_PATH:-/mnt/data/s3}:/data
|
||||
command: server /data --console-address ":9001"
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
||||
|
|
@ -57,7 +57,7 @@ services:
|
|||
redis:
|
||||
image: redis:7-alpine
|
||||
ports:
|
||||
- "6388:6379"
|
||||
- "${REDIS_PORT:-6388}:6379"
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
healthcheck:
|
||||
|
|
@ -69,9 +69,9 @@ services:
|
|||
frontend:
|
||||
build: ./frontend
|
||||
ports:
|
||||
- "8095:5173"
|
||||
- "${FRONTEND_PORT:-8095}:5173"
|
||||
environment:
|
||||
- VITE_API_URL=http://192.168.1.8:8094
|
||||
- VITE_API_URL=${VITE_API_URL}
|
||||
volumes:
|
||||
- ./frontend/src:/app/src
|
||||
- ./frontend/public:/app/public
|
||||
|
|
|
|||
Loading…
Reference in New Issue