본문으로 바로가기

[Django] Session !

category Frame Work/Django 2022. 5. 6. 01:20
728x90
반응형
 

개요

django에서 Session에 관한 기본 내용을 정리해보고자 합니다.
 

Session을 다루기 전 

Session을 다루기에 앞서  AbstractBaseUser 모델을 이용해서 테스트했습니다.. AbstractBaseUserModel은 아래 링크에서 이미 다룬 적 있습니다.

 

[Django] AbstractBaseUser Model 다루기

개요 Django Project를 처음 생성하고 migrate를 시켰을 때 사용자 모델을 입맛대로 조정할 수 있는 방법이 없나 생각하게 되었습니다. 예를 들어 userid 대신 email이나 phone을 userid로 로그인을 하려면 어

jakpentest.tistory.com

이번에 사용할 AbstractBaseUser 모델의 구성은 간략하게 다음과 같이 구성했습니다.
class User(AbstractBaseUser):
    userid = models.CharField(max_length=128, unique=True)
    password = models.CharField(_('password'), max_length=128)
    last_login = models.DateTimeField(_('last login'), blank=True, null=True)

    is_active = True

    objects = UserManager()

    USERNAME_FIELD = 'userid'
    REQUIRED_FIELDS = []

    class Meta:
        db_table = "user"
 

SessionMiddleWare?

django project를 처음 생성했을 때 middleware 관련 설정을 보면 다음과 같이 구성되었음을 알 수 있습니다.

...
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
...

MIDDLEWARE에 선언되어있는 `django.contrib.sessions.middleware.SessionMiddleware`는 request가 왔을 때 cookie 정보를 통해 session table에서 해당 데이터를 사용하고 cookie 정보가 없다면 새로운 세션을 만들어 사용합니다. 여기서 session table은 django를 migrate 했을 때 나타나는 django_session 테이블을 뜻하고 다음과 같이 구성 되어있습니다.

CREATE TABLE `django_session` (
  `session_key` varchar(40) NOT NULL,
  `session_data` longtext NOT NULL,
  `expire_date` datetime(6) NOT NULL,
  PRIMARY KEY (`session_key`),
  KEY `django_session_expire_date_a5c62663` (`expire_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
django에서 제공하는 인증 기능을 사용하면 특정 user의 session 정보는 위 테이블에 저장되어있음을 확인할 수 있습니다.

 

 

Postman을 통해서 확인해보기

SessionMiddleware 동작의 이해를 돕기 위해 Postman을 통해서 확인해보는 과정을 거쳐봅시다. 먼저 django에서 제공하는 인증 기능을 이용하기 위해 다음과 같은 view를 만듭니다.

from django.views.generic import View
from django.http.response import HttpResponse, JsonResponse
from django.contrib.auth import authenticate, login

class LoginView(View):
    def post(self, request):
    	""" 로그인
        url = r"^api/login$"
        """ 
        userid = request.POST.get("userid", None)
        password = request.POST.get("password", None)

        auth_user = authenticate(request, username=userid, password=password)
        login_user = login(request, user=auth_user)

        return HttpResponse(200)

django에서 인증 기능을 제공하는 authenticate 그리고 login 메서드 등을 이용해 간략히 로그인을 처리하는 view입니다. 이제 postman을 통해서 다음과 같이 요청을 보낼 때의 header 정보를 확인해보겠습니다.

요청 후의 Postman의 Headers는 다음과 같이 Headers에 Cookie라는 Key 값이 생겼음을 확인할 수 있습니다.

앞서 설명드렸듯 SessionMiddleware는 cookie 정보를 통해 sesison을 사용하는데 Cookie의 value를 보시면 sessionid가 들어있음을 확인할 수 있습니다. sessionid는 django_session 테이블에도 들어있음을 알 수 있습니다.

 

Session 정보를 지우고 요청했을 때?

이제 postman에서 Cookie headers 삭제하고 요청해봅시다. 삭제하는 방법은 다음과 같습니다

노란색으로 하이라이팅 부분을 클릭하면 아래와 같은 창이 나옵니다.

여기서 sessionid의 x 버튼을 눌러서 삭제한 뒤 요청해봅시다. django_session 테이블을 확인해보면 새로운 sessionid를 가진 session 정보가 생성됬음을 알 수 있습니다.

 

django SessionStore을 통해 접근해보기

django view에서 session 정보를 다룰 때 request.session을 통해 session 정보에 접근할 수 있습니다. 이때 request.session은 SessionStore 객체의 인스턴스입니다. sessionid만 있다면 SessionStore 객체를 이용해 아래와 같이 직접 가져오는 방법도 있습니다.

from django.contrib.sessions.backends.db import SessionStore

class ProfileView(View):
    def get(self, request):        
        session_store = SessionStore(session_key='...')        
        return HttpResponse(200)

사용하다 보니 알게 된 사실인데 다음과 같이 사용하는 방법에는 typing이 적용되지 않으니 불편한 감이 조금 있습니다.

session_store를 이용할 때는 아래 모양새입니다.

 

3줄 요약

지금까지 써놓았던 내용을 간단하게만 보자면 다음과 같이 정리될 수 있습니다.

1. django는 session 정보를 django_session 테이블에 저장한다.
2. session 정보를 가진 request를 보낼 때는 headers에 Cookie라는 key값을 sessionid라는 value를 저장한다.
3. request.session 말고도 SessionStore를 통해서 session 정보를 가져오는 방법도 있다.
 

서버가 확장된다면..

만약에 서버를 증설하고 각 서버에서 같은 session 정보로 인증을 해야 된다면 session 정보만 관리하는 store를 따로 두어서 session을 사용해야 되는 상황이 생길 수 있을 것 같습니다. 이런 상황에서는 SessionMiddleware를 주석 처리하고 직접 session을 관리하는 기능을 만들어서 사용할 수도 있는 스킬도 필요할 듯싶습니다.

 

728x90
반응형