본문 바로가기
웹 프로그래밍 고급 주제들

1. 쿠키와 세션 - 1.2. Why? 세션?

by 영바이트 2020. 12. 8.

 

클라이언트와 서버가 데이터를 요청하고 받을 때 마다 클라이언트를 식별할 수 있는 '쿠키'라는 작은 데이터를 클라이언트와 서버가 주고 받는 것을 '1.1. Why? 쿠키?'에서 살펴보았다. 쿠키를 이용하면 클라이언트와 서버가 서로를 알아볼 수 있는데 세션session은 또 무엇이란 말인가?

 

답부터 말하면 세션은 보안이 강화된 쿠키다. 쿠키는 사용자 정보를 쿠키에 담아서 주고 받는다. 즉, 정보가 인터넷 패킷에 담겨있다. 그런 일은 잘 일어나지 않지만 누군가 쿠키를 가지고 갈 수 있고, 쿠키 안에 담긴 정보를 볼 수도있다.

 

세션 방식에서는 정보를 옮기지 않는다. 정보는 서버에만 저장되고 정보가 들어있는 위치를 암호화해서 서버와 클라이언트가 주고 받는다. 세션 데이터가 유출되었다 하더라도 그 안에는 사용자를 식별할 수 있는 내용이 들어있지 않다. 그에 더해 세션 정보도 암호화되어 있어 '키key'가 없으면 풀 수 없다. 쿠키에 비해 훨씬 안전하다.

 

 

세션을 보안이 강화된 쿠키라고 말했다. 암호화되어 있고 그 안에 사용자를 식별할 정보를 직접 담아서 운반하지 않지만 작은 크기의 데이터를 주고 받는다는 점에서는 쿠키의 일종이라고 보는 이유가 여기에 있다.

 


 

세션을 사용하는 것은 어렵지 않다. 플라스크 웹 프레임워크가 (아주) 많은 부분을 도와주기 때문이다. 세션은 플라스크 패키지의 session 클래스를 이용해서 생성하고 관리한다. 세션은 그 사용법이 딕셔너리나 스택stack과 유사한데 먼저 세션의 생성 방법은 아래와 같다. 세션 내에 생성하려는 데이터 이름(필드field)을 지정하고 값을 대입시키면 된다.

from flask import session

session['field name'] = value

 

클라이언트와 주고 받는 세션 내의 값은 session 객체를 읽어서 가져올 수 있다. 세션의 사용 방법이 딕셔너리와 비슷하다고 한 이유가 여기에 있다.

from flask import session

value = session['field name']

 

마지막으로 세션을 삭제하는 방법은 스택stack과 비슷하다. 스택이란 데이터를 쌓고(push) 꺼내어(pop) 쓰는 데이터 구조다. 스택에서 데이터를 꺼내면 해당 데이터는 삭제된다. session 객체도 비슷한 방법을 사용한다.

from flask import session

#### field name에 해당하는 세션 항목을 삭제한다. 
#### 삭제되는 항목의 값이 반환되는데, 만약 대상 항목이 없다면 두 번째 인자로 지정한 값을 반환한다.
session.pop('field name', None)

 


 

세션도 쿠키의 활용 예라고 할 수 있기 때문에 쿠키를 연습하기 위해 위해 만들었던 예제 프로젝트를 그대로 사용할 것이다. 아래 그림과 같이 예제 프로젝트 01_cookie_session 아래에 session 디렉토리를 만들고 __init__.py, routes.py 파이썬 파일을 생성한다.

 

session 패키지 예제 구성

 

아래와 같이 세션을 생성하고, 읽고, 삭제하는 로직을 routes.py 파일 안에 구현한다.

▶ appmain/session/routes.py

from flask import Blueprint, session

sess = Blueprint('session', __name__)

@sess.route("/set_session")
def setSession():
	#### 'userName'이라는 이름의 필드를 생성하고 값을 설정한다.
    session['userName'] = 'Christophe'
    
    #### HTTP 응답의 body에 'creating a session' 메시지를 설정하고 전달한다.
    return 'creating a session'

@sess.route("/get_session")
def getSession():
    #### 'userName'이라는 이름의 필드가 session에 존재한다면 읽어온다.
    if 'userName' in session:
        return session['userName']
    else:
        return 'session does not exist'

@sess.route("/delete_session")
def deleteSession():
    #### 'userName'이라는 이름의 필드를 session에서 삭제한다.
    #### 삭제 대상 필드가 반환되는데, 대상 필드가 없다면 두 번째 인자로 지정한 값(None)이 반환된다.
    session.pop('userName', None)
    return 'session deleted'

 

예제의 session 패키지는 특별히 초기화(initiating) 해야할 내용이 없다. 따라서 초기화 파일은 비워놓았다. 굳이 나누자면 Blueprint 객체를 초기화 파일 안에서 생성해도 되는데 로직이 복잡하지 않아 따로 나누지 않고 로직 파일(routes.py) 안에 함께 구현해주었다.

 

▶ appmain/session/__init__.py

 
  
   

 

앞 서 세션을 암호화된 쿠키라고 하였다. 암호화/복호화에는 키key 라는 일정한 크기를 가지는 데이터가 필요하다. 플라스크 객체에 이 키 값을 설정해주어야 한다. 플라스크 객체는 프로젝트 최상위 패키지인 appmain 패키지의 초기화 파일 안에서 생성되고 초기화된다. appmain 패키지의 초기화 파일 안에 키 값을 설정하는 코드를 추가하자. 그리고 session 패키지에서 구현했던 세션 관리 기능을 플라스크 객체에 등록(register)한다.

 

appmain 패키지 초기화 - 키 값 설정

 

▶ appmain/__init__.py

from flask import Flask

app = Flask(__name__)

#### 암호화/복호화에 필요한 키key 값을 설정한다.
app.config['SECRET_KEY'] = 'af082ad67d6e61bf2baedc2d32af1309'

from appmain.cookie.routes import cookie

app.register_blueprint(cookie)

#### 세션 관리 기능이 구현된 Blueprint 객체를 가져온다.
from appmain.session.routes import sess

#### 세션 관리 기능이 구현된 Blueprint 객체를 플라스크 객체에 등록한다.
app.register_blueprint(sess)

 

이제 프로젝트 실행파일 run.py를 실행한 후 세션을 생성하고, 읽고, 삭제해보자.

 

 


 

예제 프로젝트 실행

 

웹 브라우저를 열고 주소창에 127.0.0.1:5000/set_session 주소를 입력하면 userName 이라는 필드에 'Cristophe' 값이 들어있는 세션이 생성된다.

 

 

세션 생선

 

생성된 세션을 웹 브라우저의 디버그 모드를 통해 확인해 볼 수 있다(크롬 브라우저의 경우 F12키).

 

생성된 세션

 

다시 주소 창에 127.0.0.1:5000/get_session을 입력해서 세션의 'userName' 필드 값을 가져와 보자. 아래와 같이 읽어온 세션의 값이 웹 브라우저에 나타날 것이다.

 

세션 값 읽어오기

 

주소 창에 127.0.0.1:5000/delete_session을 입력해서 세션의 특정 필드 값을 삭제해보자.

 

세션의 필드 값 삭제

 

웹 브라우저의 디버그 모드를 통해 세션의 내용이 삭제된 것을 확인할 수 있다. 

삭제된 세션

 

 

댓글