Este proyecto es una API RESTful desarrollada con Flask que permite la gestión de usuarios y la autenticación mediante JSON Web Tokens (JWT).
- Docker
- Docker Compose
-
Clonar el repositorio:
git clone <URL_DEL_REPOSITORIO> cd excuela
-
Construir y ejecutar los contenedores con Docker Compose:
docker-compose up --build
-
La aplicación estará disponible en
http://localhost:5000
.
La base de datos utilizada en este proyecto es Firestore, un servicio de base de datos en la nube de Firebase. Los datos de los usuarios se almacenan en una colección llamada users
.
Firebase Auth se utiliza para manejar la autenticación de usuarios. Los usuarios pueden registrarse y autenticarse mediante esta API, y sus datos se almacenan tanto en Firebase Auth como en Firestore.
Durante el registro, se crea un nuevo usuario en Firebase Auth y se almacena un documento en Firestore con la información del usuario. Aquí tienes un ejemplo de cómo se maneja en el servicio:
from firebase_admin import auth
from ..infrastructure.firebase_client import init_firebase
from ..domain.entities.user import User
from werkzeug.security import generate_password_hash
from ..infrastructure.repositories.user_repository import UserRepository
db = init_firebase()
class UserService:
@staticmethod
def register_user(username, password, email):
# Validar que el username y email sean únicos
if UserRepository.get_user_by_username(username):
raise ValueError("Username already exists")
if UserRepository.get_user_by_email(email):
raise ValueError("Email already exists")
# Crear nuevo usuario en Firebase Auth
user_record = auth.create_user(email=email, password=password)
# Crear nuevo usuario en Firestore
password_hash = generate_password_hash(password)
new_user = User(id=user_record.uid, username=username, password_hash=password_hash, email=email)
db.collection('users').document(user_record.uid).set(new_user.__dict__)
return {'message': 'User registered successfully'}
Al iniciar sesión, se valida el usuario con Firebase Auth y se genera un JSON Web Token (JWT) para la sesión del usuario. El token se obtiene utilizando la REST API de Firebase Auth. Aquí tienes un ejemplo de cómo se maneja en el servicio:
from firebase_admin import auth
from ..infrastructure.firebase_client import init_firebase
from flask_jwt_extended import create_access_token
db = init_firebase()
class UserService:
@staticmethod
def authenticate_user(data):
email = data.get('email')
password = data.get('password')
try:
user = auth.get_user_by_email(email)
if user:
# Aquí deberías validar la contraseña utilizando un servicio de validación de Firebase
token = create_access_token(identity=user.uid)
return {'access_token': token}
except auth.AuthError:
return None
Para utilizar Firebase Auth y Firestore, necesitas configurar las credenciales de Firebase en tu proyecto. Crea un archivo firebase_credentials.json y coloca tus credenciales de Firebase en él. Asegúrate de actualizar tu archivo .env para incluir la ruta a tus credenciales:
FLASK_APP=app
FLASK_ENV=development
SECRET_KEY=<TU_SECRET_KEY>
FIREBASE_APPLICATION_CREDENTIALS=firebase_credentials.json
- Ruta:
/register
- Método:
POST
- Descripción: Registra un nuevo usuario.
- Datos de entrada:
{ "username": "exampleuser", "password": "examplepassword", "email": "user@example.com" }
- Respuesta exitosa:
{ "message": "User registered successfully" }
- Errores posibles:
400 Bad Request
si elusername
oemail
ya existen.
- Ruta:
/login
- Método:
POST
- Descripción: Autentica a un usuario.
- Datos de entrada:
{ "username": "exampleuser", "password": "examplepassword" }
- Respuesta exitosa:
{ "access_token": "<JWT_TOKEN>" }
- Errores posibles:
401 Unauthorized
si las credenciales son inválidas.
- Ruta:
/user
- Método:
GET
- Descripción: Obtiene la información del usuario autenticado.
- Requiere autenticación: Sí
- Respuesta exitosa:
{ "id": "user_id", "username": "exampleuser", "email": "user@example.com", "created_at": "2023-07-13T12:34:56" }
- Ruta:
/user
- Método:
PUT
- Descripción: Actualiza la información del usuario autenticado.
- Requiere autenticación: Sí
- Datos de entrada:
{ "username": "newusername", "email": "newemail@example.com" }
- Respuesta exitosa:
{ "message": "User updated successfully" }
- Ruta:
/user
- Método:
DELETE
- Descripción: Elimina la cuenta del usuario autenticado.
- Requiere autenticación: Sí
- Respuesta exitosa:
{ "message": "User deleted successfully" }
Para ejecutar las pruebas unitarias, utiliza el siguiente comando:
docker-compose run -e FLASK_ENV=testing web pytest
El codigo ha sido organizado utilizando el patron de diseño Clean Arquitecture de esta manera:
app/
├── api/
├── config/
├── domain/
│ ├── entities/
│ └── services/
├── infrastructure/
│ ├── repository/
│ └── firebase_client.py
├── interface/
│ ├── controllers/
│ ├── decorators/
│ ├── tests/
│ └── auth.py
├── __init__.py
.env
.env.testing
conftest.py