서버 측 세션 캐싱의 기본 개념을 이해하기 위해 Python에서 웹 개발용 마이크로프레임워크인 Flask를 사용하여 작은 애플리케이션을 구현합니다. 특정 프레임워크 및 언어와 관련한 세부 사항이 아니라 개념이 중심이므로 이 예를 원하는 웹 프레임워크와 프로그래밍 언어로 변환해도 됩니다.

Flask로 시작하려면 설치 지침빠른 시작 안내서를 따르십시오.

다음은 로그인 및 로그아웃을 구현하는 매우 기본적인 애플리케이션입니다.

구문: 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('/')

나머지 예는 이 코드 조각을 기반으로 합니다. 모든 예의 코드는 이 리포지토리에서 확인할 수 있습니다.

Flask가 설치되어 있는 경우 이 앱을 부팅하려면 example-1.py라는 파일에 코드를 복사하십시오. 그런 다음 두 가지 환경 변수를 내보내야 합니다. 그 중 FLASK_APP은 example-1.py로 설정해야 하고 SECRET_KEY는 임의의 문자열(예: Y0PJWblKsg1axM4fGW)로 설정해야 합니다. 환경 변수 설정에 도움이 필요하면 Flask의 빠른 시작 안내서를 확인하십시오.

설정을 모두 마쳤으면 다음 명령을 실행합니다.

구문: 셸

$ flask run -h 0.0.0.0 -p 5000 --reload

그런 다음 http://your_flask_endpoint:5000으로 이동하면 앱이 실행되고 있을 것입니다. your_flask_endpoint는 요구 사항에서와 같이 EC2 인스턴스의 퍼블릭 DNS 이름으로 바꿔야 합니다.

사용할 수 있는 경로로는 ‘/’, ‘/login’ 및 ‘/logout’이 있습니다. 이 모든 경로를 차례로 방문하여 기본 동작을 익힐 수 있습니다.

모듈 소요 시간: 60~90분


이 예에서는 쿠키를 사용하여 사용자 이름을 저장합니다. 애플리케이션에 처음 방문할 때는 세션 객체에 저장된 사용자 이름이 없습니다. ‘/login’으로 이동하여 사용자 이름을 제공하면 해당 값이 서명된 쿠키에 저장되고 홈 페이지로 리디렉션됩니다. 그런 다음 ‘/logout’으로 이동하면 사용자 이름이 세션에서 제거되고 시작 위치로 돌아가게 됩니다.

서버 측 세션으로 이 기본 애플리케이션을 확장할 것입니다. 그러나 먼저 Redis에 연결할 수 있는지 확인하십시오.



2.1단계

(확대하려면 클릭)

2.1단계

예제에서 Redis 엔드포인트가 언급될 때마다 기본 엔드포인트의 호스트 이름을 사용해야 합니다. 

2.2단계

(확대하려면 클릭)

2.2단계

구문: 셸

$ export REDIS_URL="redis://your_redis_endpoint:6379"

구문: 셸

$ python

구문: python

>>> import redis
>>> client = redis.Redis.from_url('redis://your_redis_endpoint:6379')
>>> client.ping()

**True**

응답이 없으면 보안 그룹 설정으로 인해 차단된 것입니다. EC2 인스턴스가 ElastiCache 인스턴스에 할당된 보안 그룹에 액세스할 수 있는지 확인합니다. 예를 들어 EC2 인스턴스가 기본 보안 그룹에 할당되어 있다고 가정해보겠습니다. 이제 Amazon ElastiCache 인스턴스의 보안 그룹을 수정하고 포트 6379에서 기본 보안 그룹의 모든 인스턴스로부터의 연결을 허용하는 맞춤형 TCP 규칙을 추가할 수 있습니다. 

2.5단계

[소스]에 보안 그룹의 이름을 입력하기 시작하면 보안 그룹 ID를 클릭할 수 있습니다. 보안 그룹에 대해 자세히 알아보아야 하는 경우 설명서 또는 보안 그룹 규칙 참조를 참조하면 됩니다.


예제로 돌아가봅시다. 이제 Redis에 세션 데이터를 저장할 수 있도록 몇 가지 사항을 변경합니다. 다음은 이러한 변경 사항이 포함된 두 번째 예제입니다.

구문: 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를 가져와서 초기화하면 인덱스가 카운터를 증가시켜 사용자에게 표시합니다.

카운터를 증가시키기 위해 사용한 Redis 명령은 HINCRBY입니다. 이는 각 사용자 세션마다 Redis 해시를 사용하고 있기 때문입니다.


이제 서버 측 세션에 대한 Time To Live(TTL)를 설정합니다. 이를 위해서는 추가 코드 한 줄만 필요하며 이 코드 조각에는 / 경로만 포함됩니다.

구문: 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'
...

세션이 저장된 키는 10초 후에 만료됩니다. 이는 이 예제에만 유용한 매우 짧은 TTL입니다. 지금 애플리케이션을 실행하면 인덱스 방문 시 방문 카운터가 어떻게 업데이트되는지 알 수 있지만 해당 페이지를 방문하지 않은 채로 10초가 경과하면 다음 새로 고침 시 카운터가 1로 돌아갑니다.


이 짧은 예제는 서버 측 세션의 기본 사항을 배우기에 충분하지만 실제 상황에서의 작업은 이와 달라서, 사용자 이름을 저장하는 대신 사용자 인증 후 토큰을 생성하여 저장합니다. 이 토큰은 모든 서버 측 세션 데이터가 저장될 Redis 키를 나타냅니다. 서버 측 세션에 액세스할 때 사용자 개입 없이도 TTL이 새로 고쳐지도록 여기에 제시된 일부 동작을 추상화할 수도 있습니다. 리포지토리에는 이 동작을 추상화하는 SessionStore 클래스를 제공하는 예제가 있습니다.