En este tema, aprenderemos cómo implementar autenticación en nuestras APIs RESTful utilizando Flask. La autenticación es crucial para proteger nuestros endpoints y asegurar que solo usuarios autorizados puedan acceder a ciertos recursos.
Conceptos Clave
-
Autenticación vs. Autorización:
- Autenticación: Verificar la identidad del usuario.
- Autorización: Determinar si el usuario autenticado tiene permiso para acceder a un recurso específico.
-
Tokens de Autenticación:
- JWT (JSON Web Tokens): Un estándar abierto que define una forma compacta y autónoma de transmitir información de manera segura entre las partes como un objeto JSON.
Implementación de Autenticación con JWT
Instalación de Dependencias
Primero, necesitamos instalar las bibliotecas necesarias. Utilizaremos Flask-JWT-Extended
para manejar la autenticación con JWT.
Configuración Básica
Vamos a configurar nuestra aplicación Flask para usar JWT. Crearemos un archivo app.py
y configuraremos JWT en él.
from flask import Flask, jsonify, request from flask_jwt_extended import JWTManager, create_access_token, jwt_required, get_jwt_identity app = Flask(__name__) # Configuración de la clave secreta para JWT app.config['JWT_SECRET_KEY'] = 'super-secret-key' # Cambia esto por una clave segura en producción jwt = JWTManager(app) # Ruta de ejemplo para crear un token de acceso @app.route('/login', methods=['POST']) def login(): if not request.is_json: return jsonify({"msg": "Missing JSON in request"}), 400 username = request.json.get('username', None) password = request.json.get('password', None) if not username or not password: return jsonify({"msg": "Missing username or password"}), 400 # Aquí deberías verificar el usuario y la contraseña con tu base de datos if username != 'test' or password != 'test': return jsonify({"msg": "Bad username or password"}), 401 # Crear un nuevo token de acceso access_token = create_access_token(identity=username) return jsonify(access_token=access_token), 200 # Ruta protegida que requiere autenticación @app.route('/protected', methods=['GET']) @jwt_required() def protected(): current_user = get_jwt_identity() return jsonify(logged_in_as=current_user), 200 if __name__ == '__main__': app.run()
Explicación del Código
-
Configuración de JWT:
app.config['JWT_SECRET_KEY'] = 'super-secret-key' jwt = JWTManager(app)
Configuramos una clave secreta para firmar los tokens JWT y creamos una instancia de
JWTManager
. -
Ruta de Login:
@app.route('/login', methods=['POST']) def login(): ...
Esta ruta recibe un nombre de usuario y una contraseña, verifica las credenciales y, si son correctas, genera un token de acceso.
-
Ruta Protegida:
@app.route('/protected', methods=['GET']) @jwt_required() def protected(): ...
Esta ruta está protegida por el decorador
@jwt_required()
, lo que significa que solo se puede acceder a ella con un token JWT válido.
Ejercicio Práctico
Objetivo: Implementar una ruta de registro de usuarios y proteger un endpoint adicional.
-
Crear una Ruta de Registro:
- Añade una nueva ruta
/register
que permita a los usuarios registrarse. - Almacena los usuarios en una lista (para simplificar, no usaremos una base de datos en este ejercicio).
- Añade una nueva ruta
-
Proteger un Endpoint Adicional:
- Crea una nueva ruta
/dashboard
que solo sea accesible para usuarios autenticados.
- Crea una nueva ruta
Código de Solución:
from flask import Flask, jsonify, request from flask_jwt_extended import JWTManager, create_access_token, jwt_required, get_jwt_identity app = Flask(__name__) app.config['JWT_SECRET_KEY'] = 'super-secret-key' jwt = JWTManager(app) # Lista de usuarios (para simplificar, no usamos una base de datos) users = [] @app.route('/register', methods=['POST']) def register(): if not request.is_json: return jsonify({"msg": "Missing JSON in request"}), 400 username = request.json.get('username', None) password = request.json.get('password', None) if not username or not password: return jsonify({"msg": "Missing username or password"}), 400 # Verificar si el usuario ya existe if any(user['username'] == username for user in users): return jsonify({"msg": "User already exists"}), 400 # Registrar el nuevo usuario users.append({'username': username, 'password': password}) return jsonify({"msg": "User registered successfully"}), 201 @app.route('/login', methods=['POST']) def login(): if not request.is_json: return jsonify({"msg": "Missing JSON in request"}), 400 username = request.json.get('username', None) password = request.json.get('password', None) if not username or not password: return jsonify({"msg": "Missing username or password"}), 400 # Verificar las credenciales del usuario user = next((user for user in users if user['username'] == username and user['password'] == password), None) if not user: return jsonify({"msg": "Bad username or password"}), 401 # Crear un nuevo token de acceso access_token = create_access_token(identity=username) return jsonify(access_token=access_token), 200 @app.route('/protected', methods=['GET']) @jwt_required() def protected(): current_user = get_jwt_identity() return jsonify(logged_in_as=current_user), 200 @app.route('/dashboard', methods=['GET']) @jwt_required() def dashboard(): current_user = get_jwt_identity() return jsonify(msg=f"Welcome to your dashboard, {current_user}"), 200 if __name__ == '__main__': app.run()
Resumen
En esta sección, hemos aprendido cómo implementar autenticación en nuestras APIs RESTful utilizando JWT en Flask. Hemos cubierto la configuración básica, la creación de tokens de acceso y la protección de endpoints. Además, hemos practicado creando rutas de registro y protegiendo un endpoint adicional.
En el siguiente módulo, exploraremos cómo desplegar nuestras aplicaciones Flask en diferentes entornos de producción.
Curso de Desarrollo Web con Flask
Módulo 1: Introducción a Flask
- ¿Qué es Flask?
- Configuración de tu Entorno de Desarrollo
- Creando tu Primera Aplicación Flask
- Entendiendo la Estructura de una Aplicación Flask
Módulo 2: Conceptos Básicos de Flask
- Enrutamiento y Mapeo de URLs
- Manejo de Métodos HTTP
- Renderizando Plantillas con Jinja2
- Trabajando con Archivos Estáticos
Módulo 3: Formularios y Entrada de Usuario
Módulo 4: Integración de Bases de Datos
- Introducción a Flask-SQLAlchemy
- Definiendo Modelos
- Realizando Operaciones CRUD
- Migraciones de Base de Datos con Flask-Migrate
Módulo 5: Autenticación de Usuarios
- Registro de Usuarios
- Inicio y Cierre de Sesión de Usuarios
- Hashing de Contraseñas
- Gestión de Sesiones de Usuario
Módulo 6: Conceptos Avanzados de Flask
- Blueprints para Aplicaciones Grandes
- Manejo de Errores
- Páginas de Error Personalizadas
- Registro y Depuración
Módulo 7: APIs RESTful con Flask
- Introducción a las APIs RESTful
- Creación de Endpoints RESTful
- Manejo de Datos JSON
- Autenticación para APIs
Módulo 8: Despliegue y Producción
- Configuración de Flask para Producción
- Despliegue en Heroku
- Despliegue en AWS
- Monitoreo y Optimización del Rendimiento
Módulo 9: Pruebas y Mejores Prácticas
- Pruebas Unitarias con Flask
- Pruebas de Integración
- Cobertura de Pruebas
- Mejores Prácticas para el Desarrollo con Flask