안녕하세요. IT 엘도라도 에 오신 것을 환영합니다.
글을 쓰는 것은 귀찮지만 다시 찾아보는 것은 더 귀찮습니다.
완전한 나만의 것으로 만들기 위해 지식을 차곡차곡 저장해 보아요.   포스팅 둘러보기 ▼

장고 (Django)

[Django] 쿠키 및 세션 다루기 (+ messages, request.user)

피그브라더 2020. 7. 7. 10:53

쿠키 및 세션에 대한 기본적인 개념은 이 포스팅을 참조하기 바란다. 여기서는 그러한 쿠키와 세션을 Django에서 어떤 식으로 다룰 수 있는지, 그리고 쿠키와 세션에 기반하여 제공하는 Django의 기본적인 기능 몇 가지를 살펴보도록 한다.

 

1. Django에서 쿠키 다루기

브라우저가 Request를 보낼 때 함께 보내는 쿠키의 값들은 장고에서 request.COOKIE 객체를 통해 접근 가능하다.

 

2. Django에서 세션 다루기

해당 브라우저와의 연결 상태를 기억하고 있는 세션 저장소(이하 세션)는 장고에서 request.session 객체를 통해 접근 가능하다. 이는 장고의 기본 미들웨어인 SessionMiddleware의 역할이다. 이 미들웨어는 클라이언트가 보내는 매 요청마다 request.session 속성에 이미 생성되어 있는 세션 객체를 연결해준다.

 

만약 아직 세션이 생성되지 않은 상태라면, 세션 객체가 DB에 없다는 의미이므로 빈 껍데기의 역할만 수행하는 세션 객체를 연결해준다. 이 세션 객체는 session_key 필드의 값이 None이다. 그러나 이미 세션이 생성된 상태라면, 클라이언트가 쿠키로 보낸 세션 ID 값을 토대로 DB에서 알맞은 세션 객체를 찾아 이것을 연결해준다. 이 세션 객체는 session_key 필드의 값이 해당 세션의 ID 값이다.

 

그러나 실제로 장고로 개발할 때는 일일이 세션의 생성 여부(session_key 필드의 값이 None인지 여부)를 고려할 필요가 없는 것 같다. 단순히 request.session['name'] = '홍길동'과 같이 세션을 조작하는 작업만 수행해도 알아서 세션 ID 값이 할당되면서 세션이 생성되는 것처럼 동작하였다. 그리고 나면 응답 시에도 set_cookie 헤더에 해당 세션의 ID 값이 자동으로 설정이 된다.

 

3. messages (MessageMiddleware)

  • django.contrib.messages 앱 (INSTALLED_APPS에 기본적으로 설정되어 있음)
  • MessageMiddleware 미들웨어 (MIDDLEWARE에 기본적으로 설정되어 있음)

 

세션에 차곡차곡 저장되는 메시지 데이터들이다. 다만 request.session 객체에 저장되는 건 아니다. 세션이 아직 생성되지 않아서 세션 쿠키에 sessionid가 저장되지 않은 상태임에도 messages는 세션 쿠키에 저장되는 것을 확인하였기 때문이다. 대신, 장고의 기본 미들웨어인 MessageMiddleware가 매 요청마다 request._messages 속성에 연결해주는 메시지 저장소에 저장된다. 이후 뷰에서 해당 메시지 저장소에 몇몇 메시지들을 추가해주면 템플릿 렌더링 시 장고의 템플릿 엔진이 해당 메시지들을 소비하게 된다.

 

만약 메시지 저장소에 저장된 메시지들이 전부 소비되지 않았다면, 남은 메시지들은 클라이언트에게 전달되어 브라우저의 세션 쿠키로 저장된다. 이후 클라이언트가 다시 요청을 보내면 그때 쿠키로 날아온 남은 메시지들이 request._messages 속성에 연결될 메시지 저장소를 초기화하는 데 사용된다. 따라서 뷰에서 쌓은 메시지들을 템플릿 엔진에서 전부 소비하지 않으면 남은 메시지들이 다음 요청을 처리할 때 의도치 않게 소비될 수 있음에 주의해야 한다.

 

눈치가 빠른 사람은 request.session 객체에 저장되는 것이 아님에도 '세션에 저장'된다고 표현한 이유를 알아챘을 것이다. 사실상 위에서 말한 세션의 동작 원리와 본질적으로는 거의 동일하기 때문이다. 소비되지 못한 메시지들은 잠시 클라이언트의 브라우저 단에 저장되었다가 다시 서버 측에서 소비가 가능하기 때문에, 클라이언트와 서버의 연결 상태가 유지된다는 개념이다.

 

4. request.user (AuthenticationMiddleware)

  • django.contrib.auth 앱 (INSTALLED_APPS에 기본적으로 설정되어 있음)
  • AuthenticationMiddleware 미들웨어 (MIDDLEWARE에 기본적으로 설정되어 있음)

 

로그인한 유저 객체는 request.user 객체를 통해 접근 가능하다. 이는 장고의 기본 미들웨어인 AuthenticationMiddleware의 역할이다. 이 미들웨어는 클라이언트가 보내는 매 요청마다 request.user 속성에 로그인한 유저 객체를 연결해준다. 

 

만약 로그인하지 않은 상태라면 빈 껍데기 역할만 수행하는 유저 객체(AnonymousUser)를 연결해준다. 이 유저 객체는 is_anonymous 필드의 값이 True이다. 그러나 로그인한 상태면 클라이언트가 보낸 세션 ID 값을 토대로 DB에서 알맞은 세션 객체를 찾고 그 안에서 해당 유저의 정보를 찾아 알맞은 유저 객체를 연결해준다. 이 유저 객체는 is_anonymous 필드의 값이 False이다.

 

따라서 한 번 로그인을 하면 쿠키와 세션의 원리에 기반하여 로그인 상태가 유지될 수 있고 개발자는 request.user 객체를 통해 요청을 보낸 사용자의 정보에 쉽게 접근이 가능해진다.