반응형

 django에는 django_session 테이블이 있습니다. 말 그대로 세션 데이터를 저장하는 테이블인데요. 어떤 데이터가 저장되는지 알아보겠습니다. 저는 postgres 14.0, django는 4.0대 버전을 쓰고 있습니다.

 


 먼저, 엣지로 django admin 페이지를 열어서, 어드민 계정으로 로그인 하였습니다.

 

 

 다음에, 파이어 폭스로도 똑같이 어드민 계정으로 로그인 하였습니다. 이제, django의 session 테이블에 어떤 데이터가 저장되어 있는지 보도록 하겠습니다.

 

 

 session_key하고 session_data, 그리고 expire_date가 저장되어 있습니다. 세션 키와 세션 데이터는 어떻게 생성되는 것일까요? 그리고, 세션 키는 어디에 쓰이는 것일까요? 먼저 세션 키는 브라우저의 쿠키를 보면 어떻게 쓰이는지 예측은 할 수 있습니다.

 

 

 쿠키에 sessionid가 있는데, 이 값은 디비에서 본 session_key와 일치합니다. 이를 통해 쿠키에 있는 세션 아이디와, 디비에 있는 세션 키를 비교해서 같으면 이후 작업을 수행한다는 합리적인 추론이 가능합니다. 이제, 우리가 궁금한 것은 디비에 들어가 있는 세션키와, 세션 데이터가 어떻게 생성되는지입니다.

 


 먼저 session_key는 contrib의 session의 backends에 있는 db.py의 _get_new_session_key 함수에서 생성합니다. 이 함수의 내부를 보겠습니다.

 

 보면, session_key를 random string으로 생성함을 알 수 있습니다. 다음에, session key가 존재하지 않으면 session_key를 돌려줌을 알 수 있습니다. exists를 보면 알 수 있는데요.

 

 

 session 테이블에서 세션 키 값을 기준으로 filter를 겁니다. 만약에 있다면 exists는 참을 리턴할 겁니다.

 

 

 사실, 해당 테이블은 session을 PK로 잡아놓고 있기 때문에, 이미 있는 키를 넣으려고 하면 예외가 떨어질 겁니다. 여기까지 정리해 보겠습니다. 세션의 고유 id값을 저장하는 정보는 랜덤한 문자열을 생성한다. 중복되지 않으면 그대로 메타 정보를 넣어버린다. 그게 끝입니다. 즉, key 값은 랜덤한 문자열이다. 정도로 이해하시면 됩니다.

 

 이제 남은 것은 실제 session_data가 로그인에 성공했을 때 어떻게 들어가느냐입니다.

 


 

 session의 backends의 db.py의 create_model_instance 함수를 보면, session_data 부분이 있습니다. encode가 보이는데요. 데이터를 특정한 형식으로 인코딩을 한 결과를 넣는다는 것을 알 수 있습니다.

 

 

 데이터 값이 처음에는 빈 딕셔너리로 인코딩이 됩니다. 그 다음에 어떤 일이 일어날까요?

 

 

 세션에 대한 데이터가 하나 생성되는데요. 새로 생성된 것의 데이터가 다른 것에 비해 유독 짧다는 것을 알 수 있습니다. 해당 과정에서 수행이 된 쿼리를 보도록 하겠습니다.

 

 

 auth_user에 대해 업데이트가 이루어졌음을 알 수 있습니다. last_login이 최근 시간으로 업데이트 된 것으로 보아서 로그인이 성공하였음을 의미합니다. 그 이후에 인증에 성공한 유저의 정보를 data에 넘겨주게 됩니다.

 

 

 일단, 여기까지 정리해 봅시다. 세션 데이터는 처음에 빈 딕셔너리였어요. 그에 대한 데이터가 들어갔고, 그 다음에, 성공한 auth_user에 대한 레코드를 업데이트 합니다. 그리고 다시 인증된 유저의 정보로 session_data를 업데이트 합니다. 

 

 

 이 일련의 과정에서 등장한 쿼리들은 제가 파란색으로 표시해 놓았습니다. 그런데, 하나 궁금한 점. 왜 처음에 빈 딕셔너리였을까요?

 

 

 이는 세션이 새로 생성되면 즉시, 디비에 빠르게 넣기 때문입니다. 흐름을 정리해 보면 아래와 같을 겁니다.

 

 

 여기서 중요한 것은, 세션키를 제너레이션 하자마자 디비에 저장하는 텀을 매우 짧게 가져갔다는 것입니다. 왜? 그렇지 않으면 세션키를 제너레이트 하고, 디비에 저장하기 이전까지의 기간 동안에 다른 누군가 와서 세션키를 가져가 버릴 수 있기 때문입니다. 아. 설마 레이스 컨디션? 이제, 세션 데이터는 인코딩 된 인증된 유저에 대한 데이터라는 것을 알았습니다. 그런데 이 인증 데이터가 그대로 들어가지는 않습니다.

 

 

  decode 부분을 계속 디버그 타고 들어가다 보면 뜬금없이 compress가 나오는데요. 데이터를 압축한 다음에, 일련의 과정을 통해, 세션 데이터를 업데이트 하게 됩니다. 이에 대한 것은 다음에 이어서 해 보도록 하겠습니다.

반응형

댓글을 달아 주세요