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
