Per comprendere l’idea di base dietro al caching della sessione lato server, implementerai una piccola applicazione utilizzando Flask, un microframework per lo sviluppo web in Python. Poiché tutta l’attenzione sarà concentrata sui concetti e non sui particolari di un determinato framework e sulla lingua, puoi tradurre gli esempi nel framework web e nel linguaggio di programmazione di tua scelta.
Se desideri iniziare a usare Flask, segui le istruzioni di installazione e la guida di avvio rapido.
Di seguito è riportata un’applicazione molto semplice che ti consente di accedere e di disconnetterti:
sintassi: python
import os from flask import Flask, session, redirect, escape, request app = Flask(__name__) app.secret_key = os.environ.get('SECRET_KEY', default=None) @app.route('/') def index(): if 'username' in session: return 'Logged in as %s' % escape(session['username']) return 'You are not logged in' @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': session['username'] = request.form['username'] return redirect('/') return ''' <form method="post"> <p><input type=text name=username> <p><input type=submit value=Login> </form> ''' @app.route('/logout') def logout(): session.pop('username', None) return redirect('/')
Il resto degli esempi sarà basato su questo snippet. Il codice per tutti gli esempi è reperibile in questo repository.
Se hai installato Flask e desideri avviare questa app, copia il codice in un file denominato example-1.py. A questo punto devi esportare due variabili ambientali: FLASK_APP deve essere impostata su example-1.py e SECRET_KEY deve essere impostata su una stringa casuale, ad esempio Y0PJWblKsg1axM4fGW. Se serve aiuto per l’impostazione delle variabili ambientali, consulta la guida di avvio rapido di Flask.
Una volta completate le impostazioni, esegui questo comando:
sintassi: shell
$ flask run -h 0.0.0.0 -p 5000 --reload
Quindi accedi a http://your_flask_endpoint:5000, dove dovresti vedere la tua app in esecuzione. Devi sostituire your_flask_endpoint con il nome del DNS pubblico della tua istanza EC2, come hai fatto nei Requisiti.
Sono disponibili tre possibilità: “/”, “/login” e “/logout”. Visitale tutte a turno per acquisire familiarità con il comportamento base.
Tempo necessario per completare il modulo: 60-90 minuti
L’esempio utilizza un cookie per archiviare un nome utente. Quando visiti l’applicazione per la prima volta, non vi è alcun nome utente archiviato nell’oggetto sessione. Quando vai a “/login” e fornisci un nome utente, il valore viene archiviato in un cookie firmato e ricevi il reindirizzamento alla homepage. Quindi, se vai a “/logout”, il nome utente viene rimosso dalla sessione e torni all’inizio.
Estenderai quest’applicazione base con le sessioni lato server, ma per prima cosa assicuriamoci che tu possa connetterti a Redis.
Negli esempi, ogni volta che si cita un endpoint Redis devi utilizzare il nome host del tuo endpoint principale.
sintassi: shell
$ export REDIS_URL="redis://your_redis_endpoint:6379"
sintassi: shell
$ python
sintassi: python
>>> import redis >>> client = redis.Redis.from_url('redis://your_redis_endpoint:6379') >>> client.ping() **True**
Se si blocca, significa che sei stato bloccato dalle impostazioni del gruppo di sicurezza. Verifica che la tua istanza EC2 abbia accesso al gruppo di sicurezza assegnato alla tua istanza ElastiCache. Per esempio, supponiamo che la tua istanza EC2 sia stata assegnata al gruppo di sicurezza predefinito. Ora puoi modificare il gruppo di sicurezza della tua istanza Amazon ElastiCache e aggiungi una regola TCP personalizzata che consente connessioni sulla porta 6379 da qualsiasi istanza del gruppo di sicurezza predefinito:
In Origine, puoi iniziare a digitare il nome del gruppo di sicurezza e potrai fare clic sull'ID del gruppo di sicurezza. Se hai bisogno di saperne di più sui gruppi di sicurezza, puoi consultare la documentazione o il Riferimento alle regole del gruppo di sicurezza.
Torniamo all’esempio. Ora introdurrai alcuni piccoli cambiamenti che ti consentiranno di archiviare i dati della sessione in Radis. Ecco il secondo esempio con i cambiamenti specificati:
sintassi: python
import os import redis from flask import Flask, session, redirect, escape, request app = Flask(__name__) app.secret_key = os.environ.get('SECRET_KEY', default=None) # BEGIN NEW CODE - PART 1 # REDIS_URL = os.environ.get('REDIS_URL') store = redis.Redis.from_url(REDIS_URL) # END NEW CODE - PART 1 # @app.route('/') def index(): if 'username' in session: # BEGIN NEW CODE - PART 2 # username = escape(session['username']) visits = store.hincrby(username, 'visits', 1) return ''' Logged in as {0}.<br> Visits: {1} '''.format(username, visits) # END NEW CODE - PART 2 # return 'You are not logged in' @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': session['username'] = request.form['username'] return redirect('/') return ''' <form method="post"> <p><input type=text name=username> <p><input type=submit value=Login> </form>''' @app.route('/logout') def logout(): session.pop('username', None) return redirect('/')
Redis è ora importato e inizializzato e l’indice si occupa di incrementare un contatore e di renderlo visualizzabile dell’utente.
Il comando Redis che hai utilizzato per incrementare il contatore è HINCRBY. Il motivo è che stai utilizzando un hash Redis per la sessione di ciascun utente.
Ora imposterai un Time to Live (TTL) nella sessione lato server. È solo un’ulteriore riga di codice e tale snippet includerà soltanto la possibilità /.
sintassi: python
... @app.route('/') def index(): if 'username' in session: username = escape(session['username']) visits = store.hincrby(username, 'visits', 1) # BEGIN NEW CODE # store.expire(username, 10) # END NEW CODE # return ''' Logged in as {0}.<br> Visits: {1} '''.format(username, visits) return 'You are not logged in' ...
La chiave in cui è archiviata la sessione scadrà entro 10 secondi. È un TTL molto breve, utile solo per questo esempio. Se esegui l’applicazione ora, vedrai come visitare l’indice comporti l’aggiornamento del contatore Visite, ma se lasci passare 10 secondi senza visitare la pagina, all’aggiornamento successivo il contatore ritorna a 1.
Questo breve esempio è sufficiente ad apprendere le basi delle sessioni lato server, ma in uno scenario reale compierai altre operazioni: anziché archiviare il nome utente, genererai e archivierai un token dopo che l’utente è stato autenticato. Tale token rappresenterà la chiave Redis in cui verranno archiviati tutti i dati delle sessioni lato server. Potrebbe anche essere utile astrarre in parte il comportamento qui descritto, affinché l’eventuale accesso alla sessione lato server aggiorni il TTL senza il tuo intervento. Nel repository, troverai un esempio che fornisce una classe SessionStore che astrae il comportamento.