Session에 대한 정리 및 고찰

HTTP의 특성은 다음과 같습니다.

1. 무상태(Stateless) 프로토콜입니다.

2. 클라이언트와 서버가 요청과 응답을 주고 받으면 연결이 끊어집니다.

3. 클라이언트가 다시 요청하면 서버는 이전 요청을 기억하지 못합니다.

4. 클라이언트와 서버는 서로 상태를 유지하지 않습니다.

 

Session의 특성은 다음과 같습니다.

1. 클라이언트가 처음 서버에 연결되면 어떤 하나의 Session ID가 생성됩니다.

2. 이 아이디는 고유한 ID 입니다.

3. 이 아이디를 통해 서버는 이녀석이구나 하고 요청에 대한 응답을 할 수 있습니다.

4. 세션은 서버에 저장됩니다 ! ( 쿠키는 반면에 Client에 저장이 됩니다. )

 

즉, Client는 하나의 민증을 갖게 됩니다.

우리가 민증으로 편의점, 술집, 은행 등에서 신분을 증명하는 것과 같습니다.

 

그래서 Session이 사용자 별로 데이터를 구분할 수 있는 것입니다.

 

이러한 Session에는 보장되어야 할 것으로 Confidentiality, Data Integrity, Authenticity가 있습니다.

 

Confidentiality

기밀성으로 서버 이외에 어느 누구도 세션 데이터를 해석할 수 없어야 합니다.

 

Data Integrity

데이터 무결성으로 서버와 별개로 세션 데이터를 조작해서는 안됩니다.

 

Authenticity

진정성 (확실한 출처) 으로 서버 말고는 올바른 세션을 시작할 수 없어야 합니다.

 

이런 Session의 절차는 다음과 같습니다.

1. Client가 서버에 Resource를 요청

2. 서버에서 HTTP Request를 통해 Cookie에서 Session ID를 확인해 존재하면 이용하며 없으면 Set-Cookie를 통해 발행한 Session ID를 전송

3. Client는 HTTP Request 헤더에 Session ID를 포함해서 원하는 Resource를 요청

4. 서버에서는 Session ID를 통해 해당 Session을 찾아 Client 상태를 유지해 적절한 응답을 함

 

여기서 이런 의문이 듭니다.

🤔 엥? Session을 사용하려면 Set-Cookie를 통해 Session ID를 발행한다는게 무슨 소리..? 쿠키를 왜..

우선, HTTP 프로토콜의 특징 중 하나는 서버가 클라이언트의 요청에 응답하는 순간 HTTP 연결이 끊어지는 것입니다.

이런 HTTP 프로토콜의 특징은 웹에서 서비스를 구현할 때 큰 걸림돌이 되기도 합니다.

Stateless라는 것은 각각 요청이 독립적이어서 여러 페이지에 걸쳐 흐름이 이어져야 하는 서비스를 구현하기 어렵습니다.

 

Client와 연결이 유지되지 않는 상황에 동시에 서버로 유입되는 수많은 요청이 각각 어느 사용자의 것인지 판단하는 것은 서버에게 매우 힘든 일입니다.

 

여기서 쿠키의 힘을 느낄 수 있습니다.

서버가 Cookie를 브라우저에 저장하면, 브라우저는 해당 Cookie를 매 요청마다 서버로 보냅니다.

이러한 Cookie의 특성을 활용하면 서버는 각 요청이 어느 브라우저에서 오는 것인지 간편하게 판단합니다.

바로 Session ID를 발행하는 것입니다.

 

HttpServletRequest.getSession()을 예로 들겠습니다.

1. Session ID가 없거나 탐색이 실패하면 새로 생성하여 바인딩하고 반환합니다. ( 쿠키 기술을 사용합니다. 세션 ID를 발급하기 위해서 )

2. Client의 Session ID에 해당하는 Session을 탐색한 경우 Session을 Tracking하여 Binding하고 반환합니다.

3. Session이 Binding 되어야만 Servlet에서 Session을 사용합니다.

4. Session이 생성되어 Binding 된 경우, Session ID를 Client에 Cookie(JSESSIONID)로 전달하여 저장합니다.

 

저희는 이제 세션의 절차를 알게 되었습니다.

 

이런 코드가 있다면 어떨까요?

회원의 대표 이미지 = (세션에 저장한 회원 데이터).getUserImg();

회원의 대표 이미지는 세션에 저장된 회원 데이터의 이미지를 갖게 됩니다.

하지만, 서버에서 회원의 대표 이미지를 변경했을 때 어떻게 될까요?

세션의 회원 데이터와 서버의 회원 데이터가 서로 불일치하는 현상이 나타납니다.

 

❔ 세션의 데이터도 수정해버리면 그만 아니야?

우선 세션의 데이터를 수정하면 서버와 별개로 세션의 데이터를 수정하면 안되는 세션의 데이터 무결성을 침범해버리는 것입니다. 또한, Spring Boot Security 2.6.3 ↑ 부터는 세션의 데이터를 수정하지 않게 권장하고 있습니다.

 

이와 같은 문제로 절대로 변하지 않는 값은 세션에서 가져와서 사용하되,

변할 가능성이 있는 값은 더 신중하게 생각하고 사용할 필요가 있습니다.

 

회원 유니크한 UserNo or UserID는 변할 수가 없으니 Session에서 안전하고 유용하게 사용할 수 있을 것이나

회원의 Nickname or Img 정보 등은 변할 가능성이 있으니 Session에서 다룰 때 불안정할 수 있습니다.

 

모두 Session을 안전하고 건강하게 사용합시다 (●'◡'●)👍