1. 세션에 대해 Alaboja.
1-1. 왜 쿠키와 세션?
클라이언트와 서버가 Stateless인 HTTP 통신을 하게 되지만, 로그인과 같이 접속 정보가 저장되어야 할 때가 있다. 이때, 인증과 인가가 필요하게 된다.
인증은 클라이언트에서 보낸 정보에 담긴 ID, PW가 서버에서 저장하고 있는 정보와 일치할 때 발생한다.
그 후, 로그인 한 사용자는 자신의 계정으로 글을 쓰거나 물건을 살 때 무상태로 유지되게 되면 본인이 그 사용자임을 계속해서 인증을 해야만 하게 된다... <- 이를 해결하기 위해 서버는 인증이 된 클라이언트에게 쿠키 또는 세션을 발급해주고 클라이언트는 이를 요청 정보에 담아 보냄으로써 지속적인 인증 없이 사용자 인증이 필요한 요청들을 할 수 있게 된다.
1-2. 쿠키와 세션?
둘의 가장 큰 차이는 사용자의 정보 저장 위치이다.
쿠키는 서버 자원을 사용하지 않지만 네트워크에 부담이 갈 수 있고, 세션은 서버 자원을 사용하지만 네트워크에 부담이 가지 않는다.
보안 면에서는 세션이 더 우수하지만, 세션은 서버에서 처리하기 때문에 요청 속도는 쿠키가 더 빠르다.
쿠키도 만료시간이 있지만 파일로 저장되기 때문에 브라우저를 종료해도 정보가 남을 수 있다. (세션은 브라우저 종료시 만료시간과 무관하게 삭제)
(+ 세션은 쿠키의 트래픽 이슈와 쿠키 변경으로 인한 보안 이슈를 해결하기 위해 등장했다고 한다.)
1-3. 세션
세션은 서버로 요청하는 클라이언트를 구별하기 위해 서버에 저장되는 정보라고 할 수 있다.
서버는 Client Request에 Session Id를 생성하여 Server(세션 저장소)와 Client 환경(브라우저 메모리)에 쿠키로 저장한다. (여기서 쿠키는 일반 쿠키가 아닌 세션쿠키이며, 인 메모리 쿠키 또는 임시 쿠키, 반영구 쿠키로 불린다, 세션 쿠키는 서버 종료 / 요효기간 만료 / 브라우저 종료 시 삭제된다.)
Client는 쿠키에 있는 Session Id 값을 서버에 던지면, 서버는 해당 값이 세션 저장소에 있는지 확인하고, 세션을 넘겨준다.
1-4. 세션의 보안 issue?
Q1. 그렇다면 Session Id가 중요한 것 같은데... 쿠키의 Session Id를 다른 컴퓨터에 저장하면 로그인이 된단 말인가?
A1. 가능할 수도 있다. 근데 대부분 이런 문제는 발생하지 않는다.
무슨 말인가?
로그인이 가능한 웹사이트에서 로그인 후, JSEESIONID(톰캣 서버가 부여해준 세션 쿠키 ID)를 로그인 된 Session Id로 바꿔치기 해주면, ID PW 없이 로그인이 가능해진다. 단, SSL이 적용되지 않은 Http 사이트여야 한다.
요즘은 대부분 사이트가 Https로 SSL을 사용하기 때문에 이러한 문제는 발생하지 않는다.
- SSL이 적용되면 송수신자는 공개키-비밀키 암호화 방식을 통해 Session Id를 전달받기 때문에 송수신자가 일치하지 않으면 로그인을 시켜주지 않는다. 이로 인해 중간자 공격, 세션 하이재킹, 스니핑 공격 등으로부터 안전해진다.
Q2. 근데 쿠키에 세션 값을 보관해서 로그인을 할거면 그냥 쿠키로만 로그인 기능을 만들어도 되지 않나?
A2. 안된다. 앞서 말한대로 쿠키는 보안 위험이 크다.
대표적인 사례로는 공유 PC 접근이 있다. 공유 PC에 ID PW가 쿠키 형태로 저장되어있으면 해당 PC에서 쿠키를 누구나 볼 수 있고, 이 정보를 통해 언제 어디서든 로그인이 가능하기 때문이다.
더불어 SSL을 이용하지 않은 세션 쿠키로 구현한 로그인과 마찬가지로, XSS 공격, 스니핑 공격에도 취약하다.
Q3. 그럼 쿠키를 아예 안쓰고 서버가 사용자를 기억해서 Session을 부여해주는 방법은 없나?
A3. 없다. 그러라고 쿠키를 발급해주는 것이다.
애초에 서버가 사용자를 기억하기 위해 쿠키를 발급해주는 것이다.그게 아니면 마땅히 사용자를 식별할 매개체가 없다.
HTTP는 무상태성(Stateless)이라는 특징을 가지고있다. 서버가 클라이언트의 상태를 보존하고 있지 않는다는 뜻이다.(그래서 세션 로그인 방식은 완벽한 무상태성은 아니다.)
그래서 나온 기술이 JWT이다. 무상태성을 추구하려면 JWT 방식을 이용하는데, 클라이언트와 서버간 로그인 통신을 암호화(공개키-비밀키) 방식을 이용해서 서버는 사용자의 상태를 아예 저장하지 않는 방식으로 구현이 가능하다.
2. HttpSession에 대해 Alaboja
2-1. HttpSession?
HttpSession은 Java의 인터페이스이며, 이를 사용하여 세션을 제어할 수 있다.
우리가 사용하는 HttpSession은 Servlet Container가 생성한 인스턴스이다. Spring Web MVC를 이용해서 구현하더라도, Spring은 Servlet Container가 만든 HttpSession을 주입할 뿐, HttpSession을 생성하는 주체는 Servlet Container이다.
2-2. HttpSession 생성
{HttpServletRequestObject}.getSession()
: 기존 session이 있다면 기존 session object를, 없으면 새로 생성한 object를 반환한다.{HttpServletRequestObject}.getSession(false)
: 기존 session이 있다면 기존 session object를, 없으면 null 반환.
2-3. HttpSession 은 언제 만들어질까?
모든 요청에 대해 Sesison을 만들까? (겠냐?)
Session을 만드는 것 자체가 부담이기 때문에, Sessino을 사용할 때만 생성한다.
Spring Web MVC에서는 HttpSession을 주입해야 할 때, 내부적으로 Servlet Container에게 Sesison을 달라고 한다. httpServletRequest.getSession()
"주입해야 할 때" 즉, 주입받겠다고 선언할 때 요청한다는 말은 아니다. setAttribute getAttribute와 같이 api를 호출하는 시점에 요청/생성한다고 보면 된다.
2-4. 만료기간을 설정하는 방법
만료기간을 특정해주지 않으면 default로 30분이 설정된다.
이를 변경해주는 방법이 두 가지가 있다.
(1) web.xml의 <session-timeout>
web.xml에서 전역으로 timeout을 설정하는 방법이 있다.
가령 모든 session에 대해 15분의 만료기간을 설정하고 싶다면...<web-app> <session-config> <session-timeout>15</session-timeout> </session-config> </web-app>
이렇게 하면 된다.
(2) 특정 세션에 대해 setMaxInactiveInterval({초})
특정 세션에 대해 만료기간을 따로 설정하는 방법도 있다..session.setMaxInactiveInterval(10 * 60)
이런 식으로 10분의 timeout을 줄 수 있다.
2-5. 만료기간이 갱신된다?
세션 객체는 클라이언트가 가장 최근에 호출(접근)한 시간을 갖고 있다. -> 세션 유효 시간은 가장 최근 접근한 시간으로부터 지정된 시간까지이다. -> 접근할 때마다 갱신되고, 마지막 접근 후 지정 시간 내에 재접근이 없을 경우에 자동으로 세션은 종료된다.
찾아보지도 않고 왠지 그렇게 되는 것 같아서 10분 동안 혼자 실험을 했는데 정말 그런 것 같았고, 검색해보니 역시 그럤다... 처음부터 검색할걸...
출처
https://soon-devblog.tistory.com/2
https://life-is-potatoo.tistory.com/56
https://oh-sh-2134.tistory.com/111
'코딩 > WEB 개발' 카테고리의 다른 글
HTTP Method, PUT과 PATCH의 차이점 (0) | 2023.06.28 |
---|---|
동시 편집에 대해... (0) | 2023.06.19 |
RESTFul한 API 설계 (0) | 2023.06.14 |
자바빈즈 패턴 (JavaBeans Pattern) (0) | 2023.06.14 |
MyBatis, MyBatis-Spring 동작 원리 (0) | 2023.06.11 |