[Django-python]장고 웹 프레임워크 시작하기 - (5) 세션(Session) 옵션 과 세션 저장과 삭제

KimJiHong·2023년 9월 18일
1

Django Basics

목록 보기
5/7
post-thumbnail

지난 게시글에서 POST 방식을 이용하여 동적 웹 을 구현하는 방식과 cookie 를 사용하여 데이터를 클라이언트 (브라우저) 에 저장하여 web 에 다시 접속했을 때, 이전 데이터가 유지되도록 해봤다.

하지만, Cookie 를 사용하여 서버가 아닌 브라우저에 저장할 경우

  • 저장할 수 있는 용량이 작다 (약 4KB)
  • 상대적으로 보안에 약하다

라는 2가지 문제점이 있었다.

이번 게시글에서는 쿠키보다 속도가 느리지만, 용량에 제한이 없고 상대적으로 덜 취약한 session 을 사용하여 서버에 클라이언트의 정보를 저장해 데이터를 유지시켜보자.

현재 장고 tree

> tree

.
├─myapp
│  ├─migrations
│  │  └─__pycache__
│  ├─myapp_templates
│  └─__pycache__
└─testsite
    └─__pycache__



세션(Session)

세션(Session)을 사용해서 데이터를 유지시키려면, Django 에서 제공하는 session 관련 기능을 사용하는 것이 좋다.

그렇다면, 우선 파이썬 장고에서 기본적으로 제공하는 session 관련 기능을 알아보고 내가 원하는 설정대로 settings.py 를 수정하고, session 기능을 사용해보자.

세션 설정 (Session Options)

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초' 로 설정했다.

세션(Session) 데이터 저장

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 test

정상적으로 session 이 저장되는 것을 볼 수 있다.

세션(Session) 데이터 삭제

session 데이터가 삭제가 될려면 settings.py 에서 시간을 설정하거나, 클라이언트 측에서 웹 브라우저를 close 시 삭제가 되는데, 사용자가 웹 브라우저를 close 하거나 시간초과로 삭제가 되는것이 아닌 예를 들어, 로그아웃 버튼을 누르면 session 데이터가 삭제되게 views.pyHTML 소스를 수정해보자.

# 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!

이 된다.


이번 게시글에서는 이전 게시글에 이어서 sessioncookie 의 차이점과 설정법 및 저장과 삭제에 관하여 알아봤다.

다음 게시글에서는

  • DB 를 사용하기 위한 models.py
  • forms.py 를 사용하여 HTML 폼 설정

두가지에 대해서 알아보도록 하겠다!

전체 소스코드 Github!



틀린 부분이 있다면 지적 정말 감사합니다. 바로바로 수정하겠습니다.
profile
https://h0ng.dev

0개의 댓글

관련 채용 정보