Python Flask – Autorización de usuarios para acceder a ciertas partes de la aplicación

La autorización de usuarios en una aplicación Flask se utiliza para controlar qué partes de la aplicación pueden ser accedidas por usuarios autenticados y qué acciones pueden realizar. Flask-Login proporciona una forma sencilla de gestionar la autorización de usuarios mediante el uso del decorador @login_required para restringir el acceso a rutas específicas o vistas. Este ejemplo lo implementamos en el capítulo: Python Flask – Implementación de autenticación de usuarios

Aquí te muestro un resumen de cómo se autoriza a los usuarios para acceder a ciertas partes de tu aplicación:

1. Importar login_required de Flask-Login:

from flask_login import login_required

2. Aplicar @login_required en las rutas o vistas que requieren autorización:

@app.route('/perfil')
@login_required
def perfil():
    return render_template('perfil.html')

Con esto, Flask-Login garantizará que solo los usuarios autenticados puedan acceder a esta ruta. Si un usuario no está autenticado, será redirigido automáticamente a la página de inicio de sesión.

3. Personalizar el comportamiento de autorización:

Además de simplemente restringir el acceso, puedes personalizar aún más el comportamiento de autorización. Por ejemplo, puedes agregar roles de usuario y verificar si un usuario tiene permiso para realizar ciertas acciones. Aquí hay un ejemplo:

from flask_login import current_user

@app.route('/admin')
@login_required
def admin_panel():
    if current_user.is_admin:
        # El usuario tiene permisos de administrador
        return render_template('admin_panel.html')
    else:
        # El usuario no tiene permisos de administrador, redirigir o mostrar un mensaje de error
        flash('No tienes permisos para acceder a esta página.')
        return redirect(url_for('inicio'))

En este ejemplo, asumimos que el modelo de usuario tiene un atributo is_admin que indica si el usuario es un administrador o no.

4. Verificar permisos en las plantillas:

Puedes verificar permisos en las plantillas para mostrar u ocultar ciertas partes de la interfaz de usuario. Por ejemplo:

{% if current_user.is_admin %}
    <a href="{{ url_for('admin_panel') }}">Panel de Administración</a>
{% endif %}

Esto mostrará un enlace al “Panel de Administración” solo si el usuario actual tiene permisos de administrador.

A continuación una adaptación completa del código Python Flask – Implementación de autenticación de usuarios, se requiere agregar un template admin_panel.html, al que solo permitirá acceder al usuario administrador.

app.py

from flask import Flask, render_template, request, redirect, url_for, flash
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user

app = Flask(__name__)
app.config['SECRET_KEY'] = 'tu_clave_secreta'
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://usuario:clave@localhost/basededatos'

db = SQLAlchemy(app)
migrate = Migrate(app, db)

login_manager = LoginManager(app)
login_manager.login_view = 'login'

class Usuario(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    nombre = db.Column(db.String(80), nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    password = db.Column(db.String(128))
    is_admin = db.Column(db.Boolean, default=False)

@login_manager.user_loader
def load_user(user_id):
    return Usuario.query.get(int(user_id))

@app.route('/registro', methods=['GET', 'POST'])
def registro():
    if request.method == 'POST':
        nombre = request.form['nombre']
        email = request.form['email']
        password = request.form['password']
        es_admin = request.form.get('admin')  # Selecciona si el usuario es admin o no
        nuevo_usuario = Usuario(nombre=nombre, email=email, password=password, is_admin=es_admin)
        db.session.add(nuevo_usuario)
        db.session.commit()
        flash('¡Registro exitoso! Ahora puedes iniciar sesión.')
        return redirect(url_for('login'))
    return render_template('registro.html')

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        email = request.form['email']
        password = request.form['password']
        usuario = Usuario.query.filter_by(email=email).first()
        if usuario and usuario.password == password:
            login_user(usuario)
            flash('Inicio de sesión exitoso.')
            return redirect(url_for('perfil'))
        else:
            flash('Credenciales incorrectas. Por favor, inténtalo de nuevo.')
    return render_template('login.html')

@app.route('/perfil')
@login_required
def perfil():
    return render_template('perfil.html')

@app.route('/admin_panel')
@login_required
def admin_panel():
    if current_user.is_admin:
        # El usuario es un administrador y tiene acceso al panel de administración
        return render_template('admin_panel.html')
    else:
        flash('No tienes permisos para acceder a esta página.')
        return redirect(url_for('perfil'))

@app.route('/logout')
@login_required
def logout():
    logout_user()
    flash('Has cerrado sesión.')
    return redirect(url_for('login'))

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

templates/admin_panel.html

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Panel de Administración</title>
</head>
<body>
    <h1>Panel de Administración</h1>
    
    {% with messages = get_flashed_messages() %}
    {% if messages %}
    <ul>
        {% for message in messages %}
        <li>{{ message }}</li>
        {% endfor %}
    </ul>
    {% endif %}
    {% endwith %}
    
    <p>Bienvenido al Panel de Administración, {{ current_user.nombre }}.</p>
    
    <!-- Contenido del panel de administración -->
    
    <p><a href="{{ url_for('logout') }}">Cerrar Sesión</a></p>
</body>
</html>

Con estos pasos, puedes implementar la autorización de usuarios en tu aplicación Flask y controlar qué partes de la aplicación pueden ser accedidas por diferentes roles de usuario.

Deja un comentario