Para poder comprender la idea básica detrás del almacenamiento en caché de sesiones del lado del servidor, deberá implementar una pequeña aplicación usando Flask, un micromarco para desarrollo web en Python. Como el enfoque estará en los conceptos y no en los detalles de un marco y un lenguaje específicos, puede traducir los ejemplos al marco web y al lenguaje de programación que desee.
Si quiere comenzar con Flask, siga las instrucciones de instalación y la guía de inicio rápido.
A continuación, se muestra una aplicación muy básica que le permite iniciar y cerrar sesión:
sintaxis: 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('/')
El resto de los ejemplos se basará en este fragmento. El código para todos los ejemplos puede encontrarse en este repositorio.
Si ya ha instalado Flask y quiere iniciar esta aplicación, copie el código en un archivo llamado example-1.py. Luego, debe exportar dos variables de entornos: FLASK_APP debe establecerse en example-1.py y SECRET_KEY debe establecerse en una cadena aleatoria, como, por ejemplo, Y0PJWblKsg1axM4fGW. Si necesita ayuda para configurar las variables de entornos, consulte la guía de inicio rápido de Flask.
Cuando esté listo, ejecute este comando:
sintaxis: shell
$ flask run -h 0.0.0.0 -p 5000 --reload
A continuación, vaya a http://your_flask_endpoint:5000, donde debería ver la aplicación en ejecución. Debe reemplazar your_flask_endpoint con el nombre de DNS público de su instancia EC2, como hizo con los requisitos.
Hay tres rutas disponibles: “/”, “/login” y “/logout”. Visite todas una por vez y se familiarizará con el comportamiento básico.
Tiempo para completar el módulo: entre 60 y 90 minutos
El ejemplo usa una cookie para almacenar un nombre de usuario. Cuando visita la aplicación por primera vez, no hay ningún nombre de usuario almacenado en el objeto de la sesión. Cuando se dirige a “/login” y proporciona un nombre de usuario, el valor se almacena en una cookie firmada y se lo redirige a la página de inicio. Luego, si se dirige a “/logout”, el nombre de usuario se eliminará de la sesión y volverá donde comenzó.
Ampliará esta aplicación básica con sesiones del lado del servidor, pero primero nos aseguremos de que puede conectarse a Redis.
En los ejemplos, cada vez que se menciona el punto de enlace de Redis, debe usar el nombre de host de su punto de enlace principal.
sintaxis: shell
$ export REDIS_URL="redis://your_redis_endpoint:6379"
sintaxis: shell
$ python
sintaxis: python
>>> import redis >>> client = redis.Redis.from_url('redis://your_redis_endpoint:6379') >>> client.ping() **True**
Si no responde, significa que la configuración del grupo de seguridad lo está bloqueando. Verifique que su instancia EC2 tenga acceso al grupo de seguridad asignado a su instancia de ElastiCache. Por ejemplo, supongamos que la instancia EC2 se asignó al grupo de seguridad predeterminado. Ya puede modificar el grupo de seguridad de la instancia de Amazon ElastiCache y agregar una regla de TCP personalizada que permita las conexiones en el puerto 6379 desde cualquier instancia en el grupo de seguridad predeterminado:
En Origen, puede comenzar a escribir el nombre del grupo de seguridad y, luego, podrá hacer clic en el ID del grupo de seguridad. Si necesita obtener más información acerca de los grupos de seguridad, puede consultar la documentación o la Referencia de reglas de grupos de seguridad.
Volvamos al ejemplo. Ahora, introducirá algunos pequeños cambios que le permitirán almacenar datos de la sesión en Redis. A continuación, se muestra el segundo ejemplo con esos cambios:
sintaxis: 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 ya se ha importado e inicializado, y el índice se ocupa de incrementar el contador y de mostrárselo al usuario.
Tenga en cuenta que el comando de Redis que usó para incrementar el contador es HINCRBY. Esto se debe a que utiliza un hash de Redis para la sesión de cada usuario.
Ahora, establecerá un tiempo de vida (TTL) para la sesión del lado del servidor. Simplemente se trata de una línea de código adicional, que solo incluirá la ruta /.
sintaxis: 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 clave en la que se almacena la sesión caducará en 10 segundos. Es un TTL muy corto y solo sirve para este ejemplo. Si ejecuta la aplicación ahora, verá como se actualiza el contador de visitas con la visita al índice, pero si deja transcurrir 10 segundos sin visitar la página, el contador volverá a 1 en la próxima actualización.
Este ejemplo corto es suficiente para aprender los conceptos básicos de las sesiones del lado del servidor. Sin embargo, en una situación real, deberá hacer algo diferente: en lugar de almacenar el nombre de usuario, generará un token una vez que se autentica un usuario y lo almacenará. Ese token representará la clave de Redis bajo la cual se almacenarán todos los datos de las sesiones del lado del servidor. Además, se recomienda retirar parte del comportamiento que se encuentra aquí, de manera que cualquier acceso a la sesión del lado del servidor actualice el TTL sin que deba intervenir. En el repositorio, encontrará un ejemplo que proporciona una clase de SessionStore que retira dicho comportamiento.