En este tema, aprenderemos cómo manejar de manera segura las contraseñas de los usuarios en una aplicación Flask. El hashing de contraseñas es una técnica crucial para proteger la información sensible y evitar que las contraseñas se almacenen en texto plano.

¿Qué es el Hashing de Contraseñas?

El hashing de contraseñas es el proceso de transformar una contraseña en una cadena de caracteres irreconocible mediante una función hash. A diferencia de la encriptación, el hashing es unidireccional, lo que significa que no se puede revertir para obtener la contraseña original.

Conceptos Clave

  • Función Hash: Una función que toma una entrada (o 'mensaje') y devuelve una cadena de longitud fija, que parece aleatoria.
  • Salting: Añadir una cadena aleatoria a la contraseña antes de hashearla para proteger contra ataques de diccionario y rainbow tables.
  • Peppering: Añadir una cadena secreta adicional a la contraseña antes de hashearla, que no se almacena en la base de datos.

Herramientas para Hashing de Contraseñas en Flask

Para hashear contraseñas en Flask, utilizaremos la biblioteca werkzeug.security, que proporciona funciones seguras y fáciles de usar.

Instalación

Werkzeug es una biblioteca que viene incluida con Flask, por lo que no necesitas instalar nada adicional.

Funciones Principales

  • generate_password_hash(password, method='pbkdf2:sha256', salt_length=8): Genera un hash seguro de la contraseña.
  • check_password_hash(pwhash, password): Verifica si una contraseña coincide con su hash.

Ejemplo Práctico

Generando un Hash de Contraseña

from werkzeug.security import generate_password_hash

# Contraseña original
password = "mi_contraseña_segura"

# Generar el hash de la contraseña
hashed_password = generate_password_hash(password)

print(f"Contraseña original: {password}")
print(f"Hash de la contraseña: {hashed_password}")

Verificando una Contraseña

from werkzeug.security import check_password_hash

# Contraseña original y su hash
password = "mi_contraseña_segura"
hashed_password = generate_password_hash(password)

# Verificar la contraseña
is_correct = check_password_hash(hashed_password, password)

print(f"¿La contraseña es correcta? {'Sí' if is_correct else 'No'}")

Integración en una Aplicación Flask

Registro de Usuarios

Cuando un usuario se registra, debemos hashear su contraseña antes de almacenarla en la base de datos.

from flask import Flask, request, redirect, url_for, render_template
from werkzeug.security import generate_password_hash
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(150), unique=True, nullable=False)
    password = db.Column(db.String(200), nullable=False)

@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        hashed_password = generate_password_hash(password)
        
        new_user = User(username=username, password=hashed_password)
        db.session.add(new_user)
        db.session.commit()
        
        return redirect(url_for('login'))
    return render_template('register.html')

if __name__ == '__main__':
    db.create_all()
    app.run(debug=True)

Inicio de Sesión de Usuarios

Al iniciar sesión, debemos verificar que la contraseña proporcionada coincida con el hash almacenado.

from flask import Flask, request, redirect, url_for, render_template, session
from werkzeug.security import check_password_hash
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
app.config['SECRET_KEY'] = 'supersecretkey'
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(150), unique=True, nullable=False)
    password = db.Column(db.String(200), nullable=False)

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        
        user = User.query.filter_by(username=username).first()
        if user and check_password_hash(user.password, password):
            session['user_id'] = user.id
            return redirect(url_for('dashboard'))
        else:
            return "Nombre de usuario o contraseña incorrectos"
    return render_template('login.html')

@app.route('/dashboard')
def dashboard():
    if 'user_id' in session:
        return "Bienvenido al Dashboard"
    return redirect(url_for('login'))

if __name__ == '__main__':
    db.create_all()
    app.run(debug=True)

Ejercicio Práctico

Ejercicio

  1. Crea una aplicación Flask que permita a los usuarios registrarse y luego iniciar sesión.
  2. Asegúrate de hashear las contraseñas antes de almacenarlas en la base de datos.
  3. Verifica las contraseñas al iniciar sesión.

Solución

Puedes utilizar el código proporcionado en las secciones anteriores como base para tu aplicación.

Resumen

En esta sección, hemos aprendido sobre el hashing de contraseñas y cómo implementarlo en una aplicación Flask. Hemos cubierto:

  • Qué es el hashing de contraseñas y por qué es importante.
  • Cómo usar werkzeug.security para generar y verificar hashes de contraseñas.
  • Cómo integrar el hashing de contraseñas en el registro e inicio de sesión de usuarios en una aplicación Flask.

Con estos conocimientos, estás listo para manejar contraseñas de manera segura en tus aplicaciones Flask. En el próximo tema, aprenderemos sobre la gestión de sesiones de usuario.

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