Come proteggere una rotta Flask con una autenticazione Token-Based

Cerca

Questo articolo ha il solo scopo didattico di illustrare il meccanismo di autenticazione basato su token e il codice qui contenuto non è adeguato per un ambiente di produzione senza opportune modifiche e migliorie. Inoltre, se si vuole implementare un meccanismo di autenticazione con token, si consiglia l’introduzione nel proprio progetto Flask di PyJWT, una libreria che implementa le specifiche RFC 7519.

Autenticazione Flask basata su token

Anzitutto vediamo il codice nella sua interezza per poi procedere nei punti successivi a commentarlo pezzo per pezzo

				
					from flask import Flask, request, jsonify
import uuid
app = Flask(__name__)
# Dummy authentication credentials
USERNAME = 'admin'      # Customize it
PASSWORD = 'password'   # Customize it
# Dummy token dictionary to store authentication tokens
tokens = {}
# Route to get authentication token
@app.route('/api/v1/get-token', methods=['POST'])
def get_token():
    auth = request.authorization
    if auth and auth.username == USERNAME and auth.password == PASSWORD:
        token = uuid.uuid4().hex
        tokens[token] = {'username': auth.username}
        return jsonify({'token': token}), 200
    else:
        return jsonify({'error': 'Unauthorized access'}), 401
# Token authentication decorator
def token_required(func):
    def wrapper(*args, **kwargs):
        token = request.headers.get('Authorization')
        if token and token.split()[1] in tokens:
            return func(*args, **kwargs)
        else:
            return jsonify({'error': 'Token is missing or invalid'}), 401
    return wrapper
# Route to be protected with token authentication
@app.route('/api/your-endpoint', methods=['POST'])
@token_required
def your_endpoint():
    pass
if __name__ == '__main__':
    app.run(debug=True)
				
			

Considerazioni iniziali sulla sicurezza

Anzitutto è necessario ribadire che questo codice ha solo scopo didattico e non è adatto per la produzione. Il primo aspetto è relativo al fattore sicurezza. Ovviamente le costanti USERNAME e PASSWORD dovranno essere sostituite ed un sicuro sistema di autenticazione utente mediante username e password deve essere implementato.

Altra cosa da sostituire è il salvataggio del token e qui esistono molteplici aspetti che potrebbero essere discussi, ma che prescindono dallo scopo di questo articolo. Teniamo semplicemente a mente che salvare i token in un dizionario è una mossa non saggia e da evitare.

				
					# Dummy authentication credentials
USERNAME = 'admin'      # Customize it
PASSWORD = 'password'   # Customize it
# Dummy token dictionary to store authentication tokens
tokens = {}
				
			

Rilascio del token

L’endpoint get-token è colui che dovrà essere invocato per ottenere il token di autenticazione. In questo esempio vengono verificate le credenziali USERNAME e PASSWORD, ma come abbiamo detto nelle considerazioni precedenti, la logica di controllo dell’autenticazione va implementata ex novo.

				
					# Route to get authentication token
@app.route('/api/v1/get-token', methods=['POST'])
def get_token():
    auth = request.authorization
    if auth and auth.username == USERNAME and auth.password == PASSWORD:
        token = uuid.uuid4().hex
        tokens[token] = {'username': auth.username}
        return jsonify({'token': token}), 200
    else:
        return jsonify({'error': 'Unauthorized access'}), 401
				
			

Decoratore ed endpoint da proteggere

Questo decoratore è colui che andremo ad applicare al nostro endpoint per proteggerlo mediante autenticazione basata su token

				
					# Token authentication decorator
def token_required(func):
    def wrapper(*args, **kwargs):
        token = request.headers.get('Authorization')
        if token and token.split()[1] in tokens:
            return func(*args, **kwargs)
        else:
            return jsonify({'error': 'Token is missing or invalid'}), 401
    return wrapper
				
			

Ed ecco qui il nostro endpoint protetto

				
					# Route to be protected with token authentication
@app.route('/api/v1/your-endpoint', methods=['POST'])
@token_required
def your_endpoint():
    pass
				
			

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.

Most Recent

Come installare Borg su Synology NAS

Installare Borg su Synology NAS è cosa molto semplice da realizzare in quanto è possibile farlo mediante il package rilasciato da SynoCommunity. Vediamo in questa

Come ottenere l’URL corrente in Jinja2

Stiamo sviluppando una applicazione con Flask che usa Jinja2 come template engine. All’interno del template html che stiamo sviluppando abbiamo bisogno di ottenere l’URL corrente

Partners