En aquest tema, aprendrem com implementar l'autenticació per a APIs RESTful en Flask. L'autenticació és crucial per assegurar que només els usuaris autoritzats puguin accedir a certs recursos de l'API. Utilitzarem JSON Web Tokens (JWT) per gestionar l'autenticació.

Conceptes Clau

  1. JSON Web Tokens (JWT): Un estàndard per a la creació de tokens d'accés que permeten l'autenticació entre dues parts.
  2. Flask-JWT-Extended: Una extensió de Flask que facilita la implementació de JWT en aplicacions Flask.
  3. Protecció de Rutes: Com protegir rutes específiques perquè només els usuaris autenticats hi puguin accedir.

Instal·lació de Flask-JWT-Extended

Primer, instal·lem l'extensió Flask-JWT-Extended:

pip install Flask-JWT-Extended

Configuració Bàsica

Afegim la configuració bàsica per a JWT a la nostra aplicació Flask:

from flask import Flask, jsonify, request
from flask_jwt_extended import JWTManager, create_access_token, jwt_required, get_jwt_identity

app = Flask(__name__)

# Configuració del secret key per a JWT
app.config['JWT_SECRET_KEY'] = 'el_teu_secret_clau'  # Canvia això per una clau segura
jwt = JWTManager(app)

# Ruta per a la creació de tokens
@app.route('/login', methods=['POST'])
def login():
    if not request.is_json:
        return jsonify({"msg": "Missing JSON in request"}), 400

    username = request.json.get('username', None)
    password = request.json.get('password', None)

    if not username or not password:
        return jsonify({"msg": "Missing username or password"}), 400

    # Aquí hauries de validar l'usuari amb la teva base de dades
    if username != 'test' or password != 'test':
        return jsonify({"msg": "Bad username or password"}), 401

    access_token = create_access_token(identity=username)
    return jsonify(access_token=access_token), 200

# Ruta protegida
@app.route('/protected', methods=['GET'])
@jwt_required()
def protected():
    current_user = get_jwt_identity()
    return jsonify(logged_in_as=current_user), 200

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

Explicació del Codi

  1. Configuració del Secret Key: app.config['JWT_SECRET_KEY'] és la clau que s'utilitza per signar els tokens. Assegura't de canviar-la per una clau segura.
  2. Ruta de Login: Aquesta ruta genera un token d'accés si l'usuari proporciona les credencials correctes.
  3. Ruta Protegida: Aquesta ruta només és accessible per usuaris autenticats. Utilitza el decorador @jwt_required() per protegir-la.

Exercici Pràctic

Objectiu

Implementar una API RESTful amb autenticació JWT que permeti als usuaris registrar-se, iniciar sessió i accedir a rutes protegides.

Passos

  1. Crear una base de dades d'usuaris.
  2. Implementar la ruta de registre.
  3. Implementar la ruta de login.
  4. Protegir una ruta amb JWT.

Solució

from flask import Flask, jsonify, request
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_jwt_extended import JWTManager, create_access_token, jwt_required, get_jwt_identity

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
app.config['JWT_SECRET_KEY'] = 'el_teu_secret_clau'
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
jwt = JWTManager(app)

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

@app.route('/register', methods=['POST'])
def register():
    if not request.is_json:
        return jsonify({"msg": "Missing JSON in request"}), 400

    username = request.json.get('username', None)
    password = request.json.get('password', None)

    if not username or not password:
        return jsonify({"msg": "Missing username or password"}), 400

    hashed_password = bcrypt.generate_password_hash(password).decode('utf-8')
    new_user = User(username=username, password=hashed_password)
    db.session.add(new_user)
    db.session.commit()

    return jsonify({"msg": "User created successfully"}), 201

@app.route('/login', methods=['POST'])
def login():
    if not request.is_json:
        return jsonify({"msg": "Missing JSON in request"}), 400

    username = request.json.get('username', None)
    password = request.json.get('password', None)

    if not username or not password:
        return jsonify({"msg": "Missing username or password"}), 400

    user = User.query.filter_by(username=username).first()

    if not user or not bcrypt.check_password_hash(user.password, password):
        return jsonify({"msg": "Bad username or password"}), 401

    access_token = create_access_token(identity=username)
    return jsonify(access_token=access_token), 200

@app.route('/protected', methods=['GET'])
@jwt_required()
def protected():
    current_user = get_jwt_identity()
    return jsonify(logged_in_as=current_user), 200

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

Explicació del Codi

  1. Base de Dades d'Usuaris: Utilitzem SQLAlchemy per gestionar la base de dades d'usuaris.
  2. Ruta de Registre: Permet als usuaris registrar-se. Les contrasenyes es guarden de manera segura utilitzant bcrypt.
  3. Ruta de Login: Genera un token d'accés si les credencials són correctes.
  4. Ruta Protegida: Només accessible per usuaris autenticats.

Errors Comuns i Consells

  1. Falta de JSON en la Sol·licitud: Assegura't que les sol·licituds POST continguin JSON.
  2. Credencials Incorrectes: Proporciona missatges d'error clars quan les credencials són incorrectes.
  3. Protecció de Rutes: Utilitza @jwt_required() per protegir rutes que només han de ser accessibles per usuaris autenticats.

Conclusió

En aquest tema, hem après com implementar l'autenticació per a APIs RESTful utilitzant JWT en Flask. Hem vist com configurar l'extensió Flask-JWT-Extended, crear rutes de login i registre, i protegir rutes amb tokens JWT. Aquest coneixement és essencial per assegurar les teves APIs i garantir que només els usuaris autoritzats puguin accedir a certs recursos.

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