La gestió de sessions és una part fonamental de qualsevol aplicació web que requereixi autenticació d'usuaris. En aquest tema, aprendrem com gestionar les sessions d'usuaris en una aplicació Flask. Les sessions ens permeten mantenir l'estat de l'usuari entre diferents peticions HTTP, cosa que és essencial per a funcionalitats com l'inici de sessió.

Conceptes Clau

  • Sessió: Una sessió és un mecanisme per emmagatzemar informació específica de l'usuari en el servidor entre diferents peticions HTTP.
  • Cookies: Les cookies són petits fitxers emmagatzemats en el navegador de l'usuari que poden contenir informació de la sessió.
  • Flask-Login: Una extensió de Flask que facilita la gestió de sessions d'usuaris.

Configuració de Flask-Login

Instal·lació

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

pip install flask-login

Configuració Bàsica

  1. Inicialització de Flask-Login: Afegim la configuració bàsica per a Flask-Login en la nostra aplicació Flask.
from flask import Flask
from flask_login import LoginManager

app = Flask(__name__)
app.secret_key = 'a_very_secret_key'  # Necessari per a la gestió de sessions

login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'  # Pàgina de login
  1. Model d'Usuari: Definim un model d'usuari que Flask-Login pugui utilitzar. Aquest model ha d'implementar certs mètodes requerits per Flask-Login.
from flask_login import UserMixin

class User(UserMixin):
    def __init__(self, id, username, password):
        self.id = id
        self.username = username
        self.password = password

# Exemple d'usuaris
users = {
    1: User(1, "user1", "password1"),
    2: User(2, "user2", "password2")
}
  1. Carregador d'Usuari: Flask-Login necessita una funció per carregar un usuari des de l'ID d'usuari emmagatzemat en la sessió.
@login_manager.user_loader
def load_user(user_id):
    return users.get(int(user_id))

Inici de Sessió

Per iniciar una sessió, necessitem una ruta que gestioni el procés d'inici de sessió.

from flask import request, redirect, url_for, render_template
from flask_login import login_user

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        user = next((u for u in users.values() if u.username == username and u.password == password), None)
        if user:
            login_user(user)
            return redirect(url_for('protected'))
        else:
            return 'Invalid credentials', 401
    return render_template('login.html')

Tancament de Sessió

Per tancar una sessió, necessitem una ruta que gestioni el procés de tancament de sessió.

from flask_login import logout_user

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

Protecció de Rutes

Podem protegir rutes específiques per assegurar-nos que només els usuaris autenticats hi tinguin accés.

from flask_login import login_required

@app.route('/protected')
@login_required
def protected():
    return 'Logged in as: ' + current_user.username

Exemple Complet

Aquí teniu un exemple complet que inclou totes les peces esmentades anteriorment:

from flask import Flask, request, redirect, url_for, render_template
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user

app = Flask(__name__)
app.secret_key = 'a_very_secret_key'

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

class User(UserMixin):
    def __init__(self, id, username, password):
        self.id = id
        self.username = username
        self.password = password

users = {
    1: User(1, "user1", "password1"),
    2: User(2, "user2", "password2")
}

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

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        user = next((u for u in users.values() if u.username == username and u.password == password), None)
        if user:
            login_user(user)
            return redirect(url_for('protected'))
        else:
            return 'Invalid credentials', 401
    return render_template('login.html')

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

@app.route('/protected')
@login_required
def protected():
    return 'Logged in as: ' + current_user.username

@app.route('/')
def index():
    return 'Welcome to the Flask app!'

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

Exercicis Pràctics

  1. Afegir un Nou Usuari: Afegiu un nou usuari al diccionari users i proveu d'iniciar sessió amb aquest usuari.
  2. Personalitzar la Pàgina de Login: Modifiqueu la plantilla login.html per afegir estils CSS i millorar la seva aparença.
  3. Redirigir Després del Login: Modifiqueu la ruta /login per redirigir l'usuari a una pàgina diferent després d'iniciar sessió amb èxit.

Solucions

  1. Afegir un Nou Usuari:
users[3] = User(3, "user3", "password3")
  1. Personalitzar la Pàgina de Login:
<!-- login.html -->
<!DOCTYPE html>
<html>
<head>
    <title>Login</title>
    <style>
        body { font-family: Arial, sans-serif; }
        .login-form { max-width: 300px; margin: auto; padding: 1em; border: 1px solid #ccc; border-radius: 1em; }
        .login-form input { margin-bottom: 1em; width: 100%; padding: 0.5em; }
        .login-form button { width: 100%; padding: 0.5em; }
    </style>
</head>
<body>
    <div class="login-form">
        <form method="post">
            <label for="username">Username:</label>
            <input type="text" id="username" name="username" required>
            <label for="password">Password:</label>
            <input type="password" id="password" name="password" required>
            <button type="submit">Login</button>
        </form>
    </div>
</body>
</html>
  1. Redirigir Després del Login:
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        user = next((u for u in users.values() if u.username == username and u.password == password), None)
        if user:
            login_user(user)
            next_page = request.args.get('next')
            return redirect(next_page or url_for('protected'))
        else:
            return 'Invalid credentials', 401
    return render_template('login.html')

Conclusió

En aquesta secció, hem après com gestionar les sessions d'usuaris en una aplicació Flask utilitzant l'extensió Flask-Login. Hem cobert la configuració bàsica, la creació de rutes per iniciar i tancar sessió, i la protecció de rutes per a usuaris autenticats. Amb aquests coneixements, podeu començar a implementar funcionalitats d'autenticació en les vostres aplicacions 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