Para entender a ideia básica por trás do armazenamento em cache da sessão no servidor, você implementará um pequeno aplicativo usando o Flask, um microframework para desenvolvimento da Web em Python. Como o foco estará nos conceitos e não nos detalhes de uma determinada estrutura e linguagem, você poderá traduzir os exemplos para a estrutura da Web e a linguagem de programação de sua escolha.
Se você desejar começar a usar o Flask, siga as instruções de instalação e o guia de início rápido.
Segue abaixo um aplicativo muito básico que permite fazer login e logout:
sintaxe: 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('/')
O restante dos exemplos será baseado nesse snippet. O código para todos os exemplos pode ser encontrado neste repositório.
Se você possui o Flask instalado e deseja inicializar este aplicativo, copie o código para um arquivo chamado example-1.py. Em seguida, você precisa exportar duas variáveis de ambiente: FLASK_APP deve ser definido como example-1.py e SECRET_KEY deve ser definida como uma sequência aleatória, por exemplo Y0PJWblKsg1axM4fGW. Se você precisar de ajuda para configurar as variáveis de ambiente, consulte o guia de início rápido do Flask.
Quando estiver pronto, execute este comando:
syntax: shell
$ flask run -h 0.0.0.0 -p 5000 --reload
Em seguida, vá para http://your_flask_endpoint:5000, onde você verá seu aplicativo em execução. Você precisa substituir your_flask_endpoint pelo nome DNS público da sua instância do EC2, como fez nos Requisitos.
Existem três rotas disponíveis: “/”, “/login” e “/logout”. Visite cada uma delas de uma vez e você se familiarizará com o comportamento básico.
Tempo de conclusão do módulo: 60 - 90 minutos
O exemplo usa um cookie para armazenar um nome de usuário. Quando você visita o aplicativo pela primeira vez, não há nome de usuário armazenado no objeto da sessão. Quando você acessa "/login" e fornece um nome de usuário, o valor é armazenado em um cookie assinado e você é redirecionado para a página inicial. Então, se você for para "/logout", o nome de usuário será removido da sessão e você retornará ao ponto em que começou.
Você estenderá esse aplicativo básico com sessões do lado do servidor, mas primeiro verifique se você pode se conectar ao Redis.
syntax: shell
$ export REDIS_URL="redis://your_redis_endpoint:6379"
syntax: shell
$ python
sintaxe: python
>>> import redis
>>> client = redis.Redis.from_url('redis://your_redis_endpoint:6379')
>>> client.ping()
**True**
Se travar, significa que você está sendo bloqueado pelas configurações do Grupo de Segurança. Verifique se a sua instância do EC2 tem acesso ao grupo de segurança atribuído à sua instância do ElastiCache. Por exemplo, digamos que sua instância do EC2 foi atribuída ao grupo de segurança padrão. Agora você pode modificar o grupo de segurança da sua instância do Amazon ElastiCache e adicionar uma regra TCP personalizada, permitindo conexões na porta 6379 de qualquer instância no grupo de segurança padrão:
Na Origem, você pode começar a digitar o nome do grupo de segurança e clicar no ID do grupo de segurança. Se você precisar saber mais sobre os Grupos de Segurança, poderá verificar a documentação ou a As regras de referência do Grupo de Segurança.
Vamos voltar para o exemplo. Agora, você apresentará algumas pequenas alterações que permitirão armazenar dados da sessão no Redis. Aqui está o segundo exemplo com essas alterações:
sintaxe: 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('/')
Agora o Redis é importado e inicializado, e o índice cuida de incrementar um contador e exibi-lo ao usuário.
Observe que o comando Redis usado para incrementar o contador é HINCRBY. Isso ocorre porque você está usando um hash Redis para a sessão de cada usuário.
Agora você definirá um TTL (Time to Live) para a sessão do servidor. É apenas uma linha de código extra, e esse trecho inclui apenas a rota /.
sintaxe: 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'
...
A chave na qual a sessão está armazenada expirará em 10 segundos. É um TTL muito curto, útil apenas para este exemplo. Se você executar o aplicativo agora, verá como a visita ao índice atualiza o contador Visitas, mas se você deixar 10 segundos sem visitar a página, na próxima atualização, o contador voltará a 1.
Este pequeno exemplo é suficiente para aprender o básico das sessões do lado do servidor, mas em um cenário do mundo real, você fará algo diferente: em vez de armazenar o nome de usuário, vai gerar e armazenar um token assim que o usuário for autenticado. Esse token representará a chave Redis na qual todos os dados da sessão do servidor serão armazenados. Você também pode abstrair alguns dos comportamentos apresentados aqui, para que qualquer acesso à sessão do servidor atualize o TTL sem a sua intervenção. No repositório, você encontrará um exemplo que fornece uma classe de SessionStore que abstrai esse comportamento.
