En aquest tema, aprendrem com implementar funcionalitats d'inici i tancament de sessió d'usuaris en una aplicació Flask. Aquestes funcionalitats són essencials per a qualsevol aplicació web que requereixi autenticació d'usuaris.

Objectius

  • Entendre com gestionar sessions d'usuaris amb Flask.
  • Implementar funcionalitats d'inici de sessió.
  • Implementar funcionalitats de tancament de sessió.
  • Utilitzar Flask-Login per simplificar la gestió de sessions.

Requisits Previs

  • Coneixements bàsics de Flask.
  • Coneixements bàsics de bases de dades i models amb SQLAlchemy.
  • Coneixements bàsics de formularis amb WTForms.

Instal·lació de Flask-Login

Primer, hem d'instal·lar l'extensió Flask-Login:

pip install flask-login

Configuració de Flask-Login

  1. Configuració Bàsica

Afegim la configuració bàsica de Flask-Login a la nostra aplicació Flask:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager

app = Flask(__name__)
app.config['SECRET_KEY'] = 'el_teu_secret_clau'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
db = SQLAlchemy(app)
login_manager = LoginManager(app)
login_manager.login_view = 'login'

  1. Definició del Model d'Usuari

Definim el model d'usuari amb SQLAlchemy i Flask-Login:

from flask_login import UserMixin

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

  1. Càrrega de l'Usuari

Implementem la funció de càrrega de l'usuari:

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

Implementació de l'Inici de Sessió

  1. Formulari d'Inici de Sessió

Creem un formulari d'inici de sessió amb WTForms:

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import InputRequired, Length

class LoginForm(FlaskForm):
    username = StringField('Username', validators=[InputRequired(), Length(min=4, max=150)])
    password = PasswordField('Password', validators=[InputRequired(), Length(min=4, max=150)])
    submit = SubmitField('Login')

  1. Vista d'Inici de Sessió

Implementem la vista d'inici de sessió:

from flask import render_template, redirect, url_for, flash
from flask_login import login_user
from werkzeug.security import check_password_hash

@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(username=form.username.data).first()
        if user and check_password_hash(user.password, form.password.data):
            login_user(user)
            return redirect(url_for('dashboard'))
        else:
            flash('Invalid username or password')
    return render_template('login.html', form=form)

  1. Plantilla d'Inici de Sessió

Creem la plantilla login.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
    <h1>Login</h1>
    <form method="POST">
        {{ form.hidden_tag() }}
        <p>
            {{ form.username.label }}<br>
            {{ form.username(size=32) }}
        </p>
        <p>
            {{ form.password.label }}<br>
            {{ form.password(size=32) }}
        </p>
        <p>{{ form.submit() }}</p>
    </form>
    {% with messages = get_flashed_messages() %}
        {% if messages %}
            <ul>
                {% for message in messages %}
                    <li>{{ message }}</li>
                {% endfor %}
            </ul>
        {% endif %}
    {% endwith %}
</body>
</html>

Implementació del Tancament de Sessió

  1. Vista de Tancament de Sessió

Implementem la vista de tancament de sessió:

from flask_login import logout_user

@app.route('/logout')
def logout():
    logout_user()
    return redirect(url_for('login'))

Resum

En aquesta secció, hem après a implementar funcionalitats d'inici i tancament de sessió d'usuaris en una aplicació Flask utilitzant Flask-Login. Hem configurat l'extensió, creat el model d'usuari, implementat la vista d'inici de sessió amb validació de formularis i la vista de tancament de sessió.

Exercicis Pràctics

  1. Exercici 1: Modifica la vista d'inici de sessió per redirigir l'usuari a una pàgina diferent en funció del seu rol (per exemple, administrador o usuari normal).
  2. Exercici 2: Implementa una funcionalitat de "Recorda'm" que permeti als usuaris mantenir-se autenticats fins i tot després de tancar el navegador.

Solucions als Exercicis

Solució a l'Exercici 1

@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(username=form.username.data).first()
        if user and check_password_hash(user.password, form.password.data):
            login_user(user)
            if user.role == 'admin':
                return redirect(url_for('admin_dashboard'))
            else:
                return redirect(url_for('user_dashboard'))
        else:
            flash('Invalid username or password')
    return render_template('login.html', form=form)

Solució a l'Exercici 2

Afegim un camp "Recorda'm" al formulari d'inici de sessió:

from wtforms import BooleanField

class LoginForm(FlaskForm):
    username = StringField('Username', validators=[InputRequired(), Length(min=4, max=150)])
    password = PasswordField('Password', validators=[InputRequired(), Length(min=4, max=150)])
    remember = BooleanField('Remember Me')
    submit = SubmitField('Login')

Modifiquem la vista d'inici de sessió per utilitzar el camp "Recorda'm":

@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(username=form.username.data).first()
        if user and check_password_hash(user.password, form.password.data):
            login_user(user, remember=form.remember.data)
            return redirect(url_for('dashboard'))
        else:
            flash('Invalid username or password')
    return render_template('login.html', form=form)

Amb aquestes modificacions, hem afegit la funcionalitat de "Recorda'm" a la nostra aplicació Flask.

Curs de Desenvolupament Web amb Flask

Mòdul 1: Introducció a Flask

Mòdul 2: Conceptes Bàsics de Flask

Mòdul 3: Formularis i Entrada d'Usuari

Mòdul 4: Integració de Bases de Dades

Mòdul 5: Autenticació d'Usuaris

Mòdul 6: Conceptes Avançats de Flask

Mòdul 7: APIs RESTful amb Flask

Mòdul 8: Desplegament i Producció

Mòdul 9: Proves i Millors Pràctiques

Mòdul 10: Extensions i Ecosistema de Flask

© Copyright 2024. Tots els drets reservats