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
/registerque 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
/dashboardque 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
