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

  1. 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.
  2. 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.

pip install Flask-JWT-Extended

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

  1. 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.

  2. 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.

  3. 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.

  1. 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).
  2. Proteger un Endpoint Adicional:

    • Crea una nueva ruta /dashboard que solo sea accesible para usuarios autenticados.

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

Módulo 2: Conceptos Básicos de Flask

Módulo 3: Formularios y Entrada de Usuario

Módulo 4: Integración de Bases de Datos

Módulo 5: Autenticación de Usuarios

Módulo 6: Conceptos Avanzados de Flask

Módulo 7: APIs RESTful con Flask

Módulo 8: Despliegue y Producción

Módulo 9: Pruebas y Mejores Prácticas

Módulo 10: Extensiones y Ecosistema de Flask

© Copyright 2024. Todos los derechos reservados