지난 게시글에서 POST
방식을 이용하여 동적 웹 을 구현하는 방식과 cookie
를 사용하여 데이터를 클라이언트 (브라우저) 에 저장하여 web
에 다시 접속했을 때, 이전 데이터가 유지되도록 해봤다.
하지만, Cookie
를 사용하여 서버가 아닌 브라우저에 저장할 경우
- 저장할 수 있는 용량이 작다 (약 4KB)
- 상대적으로 보안에 약하다
라는 2가지 문제점이 있었다.
이번 게시글에서는 쿠키보다 속도가 느리지만, 용량에 제한이 없고 상대적으로 덜 취약한 session
을 사용하여 서버에 클라이언트의 정보를 저장해 데이터를 유지시켜보자.
현재 장고 tree
> tree
.
├─myapp
│ ├─migrations
│ │ └─__pycache__
│ ├─myapp_templates
│ └─__pycache__
└─testsite
└─__pycache__
세션(Session)을 사용해서 데이터를 유지시키려면, Django
에서 제공하는 session
관련 기능을 사용하는 것이 좋다.
그렇다면, 우선 파이썬 장고에서 기본적으로 제공하는 session
관련 기능을 알아보고 내가 원하는 설정대로 settings.py
를 수정하고, session
기능을 사용해보자.
Djagno
에서 세션을 사용하게 될 때, 장고에서 기본적으로 제공되는 기능 중 간단하게 주요 기능위주로 알아보자!
SESSION_ENGINE
:
세션이 저장되는 위치 설정 (default : DB 내 저장)
SESSION_COOKIE_SECURE
:
세션 쿠키를 HTTPS 통신에서만 전송하는 설정 (default : False)
SESSION_COOKIE_HTTPONLY
:
JS에서 세션 쿠키에 대한 접근을 막는 설정 (default : True)
SESSION_EXPIRE_AT_BROWSER_CLOSE
:
클라이언트가 웹 브라우저를close
시 세션 데이터 삭제 (default : False)
SESSION_COOKIE_NAME
:
세션 쿠키의 이름을 지정하는 설정 (default : 'sessionid')
SESSION_COOKIE_AGE
:
세션 쿠키 데이터의 시간(sec)을 지정하는 설정 (default : 1209600 (2주))
SESSION_SAVE_EVERY_REQUEST
:
모든request
마다 세션 데이터를save
할지 여부 (default : False)
위의 옵션들 중 원하는 옵션을 settings.py
에서 내 마음대로 설정해보자!
# settings.py
# session setting
# 클라이언트가 웹 브라우저를 close 시 세션 데이터 삭제 (default : False)
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
# 세션 쿠키 데이터의 시간(sec)을 지정하는 설정 (default : 1209600 (2주))
SESSION_COOKIE_AGE = 30
나는 클라이언트가 브라우저가 닫을 시 session
삭제, session
데이터 유지 시간을 '30초' 로 설정했다.
setting.py
에서 원하는 옵션을 선택하여 세션을 어떤식으로 사용할 것인가를 설정하였다.
이제, 진짜로 session
을 저장해보자!
이번 게시글부터는 URL 매핑에 대해서 자세한 설명은 생략하고
설명이 필요한 부분은 소스코드 내에 설명을 달겠다!
# myapp/urls.py
from django.urls import path
from . import views
urlpatterns = [
# session 을 사용해볼 urls 패턴 추가
# URL 패턴명은 'using_session' 으로 정의했음!
,path('session', views.POST_index_session, name='using_session')
]
# myapp/views.py
from django.shortcuts import HttpResponse
from django.shortcuts import render, redirect
def POST_index_session(request):
# POST
if request.method == 'POST':
# form의 'text_data_input' 에 입력한 데이터를 불러옴
data = request.POST.get('text_data_input')
# 'text_data_session' 이라는 이름으로 data 를 저장하고
# settings.py 에서 설정했던 것처럼 DB 내에 저장
request.session['text_data_session'] = data
return redirect('using_session')
# GET
else:
# DB 내에 request 한 클라이언트 의 session 데이터중
# 'text_data_session' 이 있는지 검사
# True : session data load
# False : None
data = request.session.get('text_data_session', None)
context = {'text_data' : data}
return render(request, 'post_index.html', context)
<!-- myapp/myapp_templates/post_index.html -->
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>POST방식</title>
</head>
<body>
<h1>TEST_kimjihong</h1>
<div>안녕하세요?</div>
<!-- action 속성은 데이터가 전송될 URL 패턴을 지정.
지난 게시글에서의 urls.py에서 별칭(name) 파라미터-->
<form action="" method="post">
<!-- ※중요※
장고 에서 POST 요청을 보낼 때 CSRF 보호 기능을 사용하려면,
꼭! form 태그 내부에 이 csrf_token 태그를 포함시켜야 한다. -->
{% csrf_token %}
<div>
<input type="text" name="text_data_input">
</div>
<div>
<input type="submit" value="세션저장" name="action">
</div>
</form>
<!-- DTL(장고 템플릿 언어)의 if문.
text_data가 있다면 endif 까지의 내용을 출력
즉, text_data라는 데이터(context)가 있다면 출력 -->
{% if text_data %}
<div>
{{ text_data }}
</div>
<!-- DTL if 문 종료 -->
{% endif %}
</body>
</html>
이제 실행결과를 확인해보면
정상적으로 session
이 저장되는 것을 볼 수 있다.
session
데이터가 삭제가 될려면 settings.py
에서 시간을 설정하거나, 클라이언트 측에서 웹 브라우저를 close
시 삭제가 되는데, 사용자가 웹 브라우저를 close
하거나 시간초과로 삭제가 되는것이 아닌 예를 들어, 로그아웃 버튼을 누르면 session
데이터가 삭제되게 views.py
와 HTML
소스를 수정해보자.
# myapp/views.py
from django.shortcuts import HttpResponse
from django.shortcuts import render, redirect
def POST_index_session(request):
# POST
if request.method == 'POST':
if request.POST.get('action') == '세션저장':
# form의 'text_data_input' 에 입력한 데이터를 불러옴
data = request.POST.get('text_data_input')
# 'text_data_session' 이라는 이름으로 data 를 저장하고
# settings.py 에서 설정했던 것처럼 DB 내에 저장
request.session['text_data_session'] = data
return redirect('using_session')
elif request.POST.get('action') == '세션삭제':
# DB 내에 request 한 클라이언트 의 session 데이터중
# 'text_data_session' 이 있는지 검사
# True : session data load
# False : None
session_data = request.session.get('text_data_session', None)
if session_data:
# 'text_data_session' 의 정보를 session 에서 삭제
del request.session['text_data_session']
return redirect('using_session')
# GET
else:
data = request.session.get('text_data_session', None)
context = {'text_data' : data}
return render(request, 'post_index.html', context)
<!-- myapp/myapp_templates/post_index.html -->
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>POST방식</title>
</head>
<body>
<h1>TEST_kimjihong</h1>
<div>안녕하세요?</div>
<!-- action 속성은 데이터가 전송될 URL 패턴을 지정.
지난 게시글에서의 urls.py에서 별칭(name) 파라미터-->
<form action="" method="post">
<!-- ※중요※
장고 에서 POST 요청을 보낼 때 CSRF 보호 기능을 사용하려면,
꼭! form 태그 내부에 이 csrf_token 태그를 포함시켜야 한다. -->
{% csrf_token %}
<div>
<input type="text" name="text_data_input">
</div>
<div>
<!-- 같은 name 을 사용하여
views.py 에서 value 값을 검사하여
원하는 logic 을 넣을 수 있다. -->
<input type="submit" value="세션저장" name="action">
<input type="submit" value="세션삭제" name="action">
</div>
</form>
<!-- DTL(장고 템플릿 언어)의 if문.
text_data가 있다면 endif 까지의 내용을 출력
즉, text_data라는 데이터(context)가 있다면 출력 -->
{% if text_data %}
<div>
{{ text_data }}
</div>
<!-- DTL if 문 종료 -->
{% endif %}
</body>
</html>
여기서, 주의 해야할 점은 HTML
소스에서
<!-- html -->
<input type="submit" value="세션저장" name="action">
<input type="submit" value="세션삭제" name="action">
하나의 form
내에서 같은 name
을 사용하여 value
를 검사하여 '세션 데이터를 저장할 것' 인지 '세션 데이터를 삭제할 것' 인지에 대한 로직
# views.py
# POST method 데이터 => {'action' : '세션저장'}
if request.POST.get('action') == '세션저장':
# session save logic !
# POST method 데이터 => {'action' : '세션삭제'}
elif request.POST.get('action') == '세션삭제':
# session del logic !
을 꼭 작성해야한다!
이제 위 소스들을 실행해보면, django
내 DB 에 session
데이터가 저장되었고
세션이 만료되기위한 조건은
세션(session) 만료
- 클라이언트 측에서 웹 브라우저 close
- settings.py 에서 설정한 session 제한 시간인 30초 경과
- '세션삭제' 버튼 click!
이 된다.
이번 게시글에서는 이전 게시글에 이어서 session
과 cookie
의 차이점과 설정법 및 저장과 삭제에 관하여 알아봤다.
다음 게시글에서는
models.py
forms.py
를 사용하여 HTML
폼 설정두가지에 대해서 알아보도록 하겠다!