En esta sección, aprenderemos cómo implementar el registro de usuarios en una aplicación Flask. El registro de usuarios es una funcionalidad esencial para muchas aplicaciones web, ya que permite a los usuarios crear cuentas y acceder a servicios personalizados.

Objetivos

  • Crear un formulario de registro de usuario.
  • Validar los datos del formulario.
  • Guardar la información del usuario en la base de datos.
  • Proporcionar retroalimentación al usuario sobre el estado del registro.

Requisitos Previos

Antes de comenzar, asegúrate de haber completado los módulos anteriores, especialmente aquellos relacionados con formularios y bases de datos.

Paso 1: Crear el Formulario de Registro

Primero, necesitamos crear un formulario de registro utilizando WTForms. Vamos a definir un formulario que capture el nombre de usuario, el correo electrónico y la contraseña del usuario.

# forms.py
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Email, EqualTo, Length

class RegistrationForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired(), Length(min=2, max=20)])
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    confirm_password = PasswordField('Confirm Password', validators=[DataRequired(), EqualTo('password')])
    submit = SubmitField('Sign Up')

Explicación del Código

  • StringField, PasswordField, y SubmitField son campos de formulario proporcionados por WTForms.
  • DataRequired, Email, EqualTo, y Length son validadores que aseguran que los datos ingresados cumplen con ciertos criterios.

Paso 2: Crear la Ruta de Registro

A continuación, creamos una ruta en nuestra aplicación Flask para manejar el registro de usuarios.

# routes.py
from flask import render_template, url_for, flash, redirect
from app import app, db
from app.forms import RegistrationForm
from app.models import User

@app.route("/register", methods=['GET', 'POST'])
def register():
    form = RegistrationForm()
    if form.validate_on_submit():
        user = User(username=form.username.data, email=form.email.data, password=form.password.data)
        db.session.add(user)
        db.session.commit()
        flash('Your account has been created!', 'success')
        return redirect(url_for('login'))
    return render_template('register.html', title='Register', form=form)

Explicación del Código

  • @app.route("/register", methods=['GET', 'POST']): Define la ruta para el registro de usuarios.
  • form.validate_on_submit(): Verifica si el formulario ha sido enviado y si los datos son válidos.
  • User(username=form.username.data, email=form.email.data, password=form.password.data): Crea una nueva instancia del modelo User.
  • db.session.add(user), db.session.commit(): Guarda el nuevo usuario en la base de datos.
  • flash('Your account has been created!', 'success'): Muestra un mensaje de éxito al usuario.
  • redirect(url_for('login')): Redirige al usuario a la página de inicio de sesión después del registro exitoso.

Paso 3: Crear la Plantilla de Registro

Ahora, creamos una plantilla HTML para el formulario de registro.

<!-- templates/register.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ title }}</title>
</head>
<body>
    <h2>Register</h2>
    <form method="POST" action="{{ url_for('register') }}">
        {{ form.hidden_tag() }}
        <div>
            {{ form.username.label }}<br>
            {{ form.username(size=32) }}<br>
            {% for error in form.username.errors %}
                <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </div>
        <div>
            {{ form.email.label }}<br>
            {{ form.email(size=32) }}<br>
            {% for error in form.email.errors %}
                <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </div>
        <div>
            {{ form.password.label }}<br>
            {{ form.password(size=32) }}<br>
            {% for error in form.password.errors %}
                <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </div>
        <div>
            {{ form.confirm_password.label }}<br>
            {{ form.confirm_password(size=32) }}<br>
            {% for error in form.confirm_password.errors %}
                <span style="color: red;">[{{ error }}]</span>
            {% endfor %}
        </div>
        <div>
            {{ form.submit() }}
        </div>
    </form>
</body>
</html>

Explicación del Código

  • {{ form.hidden_tag() }}: Incluye un campo oculto para proteger contra ataques CSRF.
  • {{ form.username.label }}, {{ form.username(size=32) }}: Renderiza la etiqueta y el campo de entrada para el nombre de usuario.
  • {% for error in form.username.errors %}: Muestra los errores de validación para el campo de nombre de usuario.

Paso 4: Hashing de Contraseñas

Es importante no almacenar contraseñas en texto plano. Vamos a usar werkzeug.security para hash de contraseñas.

# models.py
from app import db
from werkzeug.security import generate_password_hash, check_password_hash

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    password_hash = db.Column(db.String(128), nullable=False)

    def set_password(self, password):
        self.password_hash = generate_password_hash(password)

    def check_password(self, password):
        return check_password_hash(self.password_hash, password)

Explicación del Código

  • generate_password_hash(password): Genera un hash seguro para la contraseña.
  • check_password_hash(self.password_hash, password): Verifica si la contraseña proporcionada coincide con el hash almacenado.

Paso 5: Actualizar la Ruta de Registro

Finalmente, actualizamos la ruta de registro para usar el método set_password.

# routes.py
@app.route("/register", methods=['GET', 'POST'])
def register():
    form = RegistrationForm()
    if form.validate_on_submit():
        user = User(username=form.username.data, email=form.email.data)
        user.set_password(form.password.data)
        db.session.add(user)
        db.session.commit()
        flash('Your account has been created!', 'success')
        return redirect(url_for('login'))
    return render_template('register.html', title='Register', form=form)

Ejercicio Práctico

Ejercicio

  1. Implementa una funcionalidad que verifique si el nombre de usuario o el correo electrónico ya están en uso antes de crear un nuevo usuario.
  2. Añade un campo de confirmación de correo electrónico y valida que coincida con el campo de correo electrónico.

Solución

  1. Verificación de nombre de usuario y correo electrónico:
@app.route("/register", methods=['GET', 'POST'])
def register():
    form = RegistrationForm()
    if form.validate_on_submit():
        existing_user = User.query.filter((User.username == form.username.data) | (User.email == form.email.data)).first()
        if existing_user:
            flash('Username or email already in use', 'danger')
        else:
            user = User(username=form.username.data, email=form.email.data)
            user.set_password(form.password.data)
            db.session.add(user)
            db.session.commit()
            flash('Your account has been created!', 'success')
            return redirect(url_for('login'))
    return render_template('register.html', title='Register', form=form)
  1. Campo de confirmación de correo electrónico:
# forms.py
class RegistrationForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired(), Length(min=2, max=20)])
    email = StringField('Email', validators=[DataRequired(), Email()])
    confirm_email = StringField('Confirm Email', validators=[DataRequired(), Email(), EqualTo('email')])
    password = PasswordField('Password', validators=[DataRequired()])
    confirm_password = PasswordField('Confirm Password', validators=[DataRequired(), EqualTo('password')])
    submit = SubmitField('Sign Up')

Conclusión

En esta sección, hemos aprendido cómo implementar el registro de usuarios en una aplicación Flask. Hemos cubierto la creación de formularios, la validación de datos, el almacenamiento seguro de contraseñas y la retroalimentación al usuario. En el próximo tema, abordaremos el inicio y cierre de sesión de usuarios.

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