장고에서 View를 작성할때도 나오는 Http란 인터넷에서 서버와 클라이언트가 데이터를 주고 받을 때 사용하는 통신규약(Protocol)이다.
Http의 특징중 하나로 Stateless(connectionless)가 있는데, 클라이언트(사용자)가 요청을 보내고 서버(Django)가 request를 주면 그대로 연결이 끊긴다는 뜻이다.
웹서버의 특성상 다수의 사용자가 정보를 요구하는 경우가 많은데, 이에 대해 사용자와 연결을 유지하려면 서버에 많은 리소스 낭비가 생기게 된다.
하지만 Http Protocol의 경우 응답을 주고 곧바로 연결을 끊기에 리소스 낭비를 줄인다는 장점이 있다.
연결이 끊기는 Http의 특징때문에 Login기능과 같은 사용자의 정보를 유지시켜야 하기 위해 사용하게 되는 것이 Session과 Cookie다.
쿠키는 클라이언트 측에서 로컬 웹 브라우저(Chrome, IE, ...)가 저장하는 데이터다.
인증을 하기위한 과정에서 처음에 서버는 쿠키를 생성해서 클라이언트에게 보내게된다면, 클라이언트는 쿠키를 웹 브라우저에 저장한다.
이후 클라이언트가 데이터 요청시 Http헤더에 쿠키를 실어서 서버에 보내게된다.
따라서 로그인 정보가 쿠키에 담겨져있다면 더이상의 인증은 필요없게된다.
세션도 쿠키와 동일하게 클라이언트의 인증 상태 정보를 저장할 수 있게되는데, 쿠키와 상이한 점은 데이터를 서버에 저장되며 Session id와 쿠키를 이용한다는 점이다.
쿠키에 세션의 ID를 함께 보냄으로써 세션ID를 통해 서버는 각 사용자를 구별 할 수 있게된다.
또한 이러한 세션의 ID는 랜덤 문자열로 부여하기 때문에 외부에서 세션 정보를 열람하여도 개인 로그인 정보와 매칭이 불가능하다는 특징이 있다.
쿠키와 세션의 차이점
쿠키(Cookie) 세션(Session) 저장 위치 클라이언트 (사용자 pc 브라우저) 서버 저장 형식 text Object (django의 경우 model) 만료 시점 쿠키 저장시 설정(default : 브라우저 종료시점) 알 수 없음 용량 제한 브라우저별로 상이 (평균 4kb) 제한 없음 속도 ▲ ▼ 보안 ▼ ▲
세션이 쿠키에 비해 모든 면에서 좋아보이나 사용하는 이유는
세션은 서버에 저장되고, 서버자원을 사용하기 때문에 사용자가 많을 경우 많은 자원을 소모하게도니다.
이때문에 자원관리 차원에서 쿠키와 세션을 적절한 요소 및 기능에 병행 사용하여,
서버 자원의 낭비를 방지할 수 있다.
장고의 세션 프레임 워크를 사용하면 사이트 방문자별로 임의의 데이터를 저장하고 검색 할 수 있다.
보다 자세한 내용은 공식 문서를 참고하길 바란다.
settings.py 파일에 아래의 내용을 추가해서 장고의 세션 기능을 활성화한다.
MIDDLEWARE = [
...
'django.contrib.sessions.middleware.SessionMiddleware',
...
]
DB로 세션을 관리하길 원하면 위와같은 settings.py 파일에서
INSTALLED_APPS = [
...
'django.contrib.sessions',
...
]
를 작성한 후 migrate를 사용해 데이터베이스 모델을 생성한다.
settings 파일에 다음과 같이 세션쿠키의 만료 시점을 설정할 수 있다.
SESSION_COOKIE_AGE = 600 # 세션쿠키의 유효기간 설정(default: 2주)
SESSION_SAVE_EVERY_REQUEST = True # 서버에게 Request를 보낼 경우 시간 초기화
모델 사용
위와 같이 설정할 경우 django.contrib.sessions.models.Session라는 모델에서 사용할 수 있다.
다른 엔진으로 쿠키, 파일 기반으로 사용할 수 있다.
아래는 세션 모델의 구조이다.
실질적으로 사용하기 위한 View에서 session을 다루는 법이다.
두 가지 정도의 방법들을 발견했다.
from django.contrib.sessions.backends.db import SessionStore
def index(request):
...
# 방법 1
s = SessionStore()
s['key'] = 'value'
s.create()
# 방법 2
request.session['key'] = value
...
return render(request, 'index.html')
request.session 으로 접근 할 수 있다.
from django.contrib.sessions.models import Session
def index(request):
...
request.session['key'] = 'value' # 세션에 {"key":"value"} 데이터 추가
request.session.get('key', False) # 데이터에 'key'의 값 반환 없으면 False
request.session.clear_expired() # 만료된 세션 삭제
request.session.session_key # session ID(session key) 반환
if(request.session.session_key): # 사용자의 session이 만들어져있는지 확인
s = Session.objects.get(pk = request.session.session_key)
print(s.get_decoded()) # session의 데이터를 디코딩해서 반환
return render(request, 'index.html')
session의 타입
reuqest.session : django.contrib.sessions.backends.db.SessionStore
reuqest.session['key'] : dict
s : django.contrib.sessions.models.Session
s.get_decoded() : dict
Login 같은 경우를 처리할 땐 Session의 생성 부분을 참조하여 사용자를 특정한다.
Logout은 다음과 같이 처리하여 간편하게 DB모델에서도 삭제 될 수 있게 하자.
from django.contrib.auth import logout
def index(request):
logout(request)
...
감사합니다~!