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
- JSON Web Tokens (JWT): Un estàndard per a la creació de tokens d'accés que permeten l'autenticació entre dues parts.
- Flask-JWT-Extended: Una extensió de Flask que facilita la implementació de JWT en aplicacions Flask.
- 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:
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
- 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. - Ruta de Login: Aquesta ruta genera un token d'accés si l'usuari proporciona les credencials correctes.
- 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
- Crear una base de dades d'usuaris.
- Implementar la ruta de registre.
- Implementar la ruta de login.
- 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
- Base de Dades d'Usuaris: Utilitzem SQLAlchemy per gestionar la base de dades d'usuaris.
- Ruta de Registre: Permet als usuaris registrar-se. Les contrasenyes es guarden de manera segura utilitzant bcrypt.
- Ruta de Login: Genera un token d'accés si les credencials són correctes.
- Ruta Protegida: Només accessible per usuaris autenticats.
Errors Comuns i Consells
- Falta de JSON en la Sol·licitud: Assegura't que les sol·licituds POST continguin JSON.
- Credencials Incorrectes: Proporciona missatges d'error clars quan les credencials són incorrectes.
- 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
- Què és Flask?
- Configuració del Teu Entorn de Desenvolupament
- Creant la Teva Primera Aplicació Flask
- Entenent l'Estructura d'una Aplicació Flask
Mòdul 2: Conceptes Bàsics de Flask
- Enrutament i Mapeig d'URL
- Gestió de Mètodes HTTP
- Renderització de Plantilles amb Jinja2
- Treballant amb Fitxers Estàtics
Mòdul 3: Formularis i Entrada d'Usuari
Mòdul 4: Integració de Bases de Dades
- Introducció a Flask-SQLAlchemy
- Definició de Models
- Realització d'Operacions CRUD
- Migracions de Bases de Dades amb Flask-Migrate
Mòdul 5: Autenticació d'Usuaris
- Registre d'Usuaris
- Inici i Tancament de Sessió d'Usuaris
- Hashing de Contrasenyes
- Gestió de Sessions d'Usuaris
Mòdul 6: Conceptes Avançats de Flask
- Blueprints per a Aplicacions Grans
- Gestió d'Errors
- Pàgines d'Error Personalitzades
- Registre i Depuració
Mòdul 7: APIs RESTful amb Flask
- Introducció a les APIs RESTful
- Creació de Punts Finals RESTful
- Gestió de Dades JSON
- Autenticació per a APIs
Mòdul 8: Desplegament i Producció
- Configuració de Flask per a Producció
- Desplegament a Heroku
- Desplegament a AWS
- Monitorització i Optimització del Rendiment
Mòdul 9: Proves i Millors Pràctiques
- Proves Unitàries amb Flask
- Proves d'Integració
- Cobertura de Proves
- Millors Pràctiques per al Desenvolupament amb Flask