로그인 - 쿠키, 세션

zunzero·2022년 8월 27일
0

스프링, JPA

목록 보기
7/23

HTTP

HTTP는 클라이언트와 서버 사이에 이루어지는 요청/응답 프로토콜이다. 즉, 클라이언트와 서버 사이의 의사소통 방식이라고 생각하면 된다.
HTTP는 비연결성(Connectionless)과 무상태(Stateless)라는 특성을 가진다.
비연결성은 클라이언트의 요청와 서버의 응답 이후 연결이 끊기는 성질을 의미한다.
무상태란 HTTP의 비연결적인 특성으로 인해, 연결이 해제됨과 동시에 서버와 클라이언트는 이전 요청에 대한 결과를 잊어버리게 되는 특성을 의미한다.
예를 들자면, A가 로그인 이후에 A가 다시 요청을 보내면 서버는 이 요청이 A로부터 온 요청이라는 것을 알 수 없다는 것이다.
그래서 HTTP는 'Stateless Protocol'이라 불린다.
이는 독립적인 쌍의 요청과 응답을 처리함으로 단순하고, 상태를 저장해야 하는 서버의 부담을 감소시킬 수 있다.
이렇게 Stateless한 HTTP를 통해 로그인 기능을 구현할 때 등장하는 것이 쿠키와 세션이다.

쿠키

웹 브라우저에는 쿠키 저장소라는 것이 따로 있다.
웹 브라우저는 쿠키 저장소에 쿠키를 보관할 수 있고, 서버로 요청을 보낼 때 이 쿠키 저장소라는 것을 뒤져서 쿠키를 요청에 함께 보낼 수 있다.

A가 서버에 로그인 요청을 보내면 서버는 응답으로 '로그인 성공' 메세지와, 로그인 유저에 대한 정보를 쿠키에 담아서 응답할 수 있다.

브라우저는 쿠키를 쿠키 저장소에 보관하고, 이후 모든 요청에 쿠키를 함께 보내 해당 요청의 주인이 누구인지 서버가 알게 할 수 있다.

쿠키의 보안 문제

위 사진의 예시를 보면, 쿠키에 memberId라는 이름으로 회원의 id 값이 저장되어 있다.
쿠키는 모두에게 공개되며 임의로 변경될 수 있기 때문에 쿠키에 직접적인 데이터를 담아 보내는 것은 위험하다. (쿠키에 보관된 정보는 도난 당할 수 있기 때문에 보안상 안전하지 못하다.)

이에 대한 대안으로 떠오른 것이 세션이다.
쿠키에 중요한 값을 노출하지 않고, 사용자 별로 예측 불가능한 랜덤값을 노출하고, 서버에서는 {key, value} 형태로 {랜덤값, 회원 id} 값을 저장해두는 것이다.
쿠키값으로 전해온 랜덤값을 통해 회원 id를 찾아 해당 요청의 주인이 누구인지 식별할 수 있는 것이다.
예측이 불가능한 랜덤값이기 때문에 해커가 임의로 변경하기 쉽지 않고, 시간이 지나면 사용할 수 없도록 적절한 만료시간을 설정해두어야 한다.

세션

세션의 동작 방식은 다음과 같다.

1. 사용자가 아이디와 패스워드 정보를 전송하면, 서버에서는 로그인 성공/실패 여부를 확인한다.
2. 추적 불가능한 세션ID를 생성해서, 생성된 세션ID와 세션에 보관할 값을 서버의 세션 저장소에 보관한다.
3. 서버는 클라이언트에 세션ID만 응답 쿠키로 하여 응답한다.
4. 클라이언트는 쿠키 저장소에 세션ID 쿠키를 저장하고, 요청마다 함께 전송한다.
5. 서버에서는 클라이언트가 전달한 쿠키 정보로 세션 저장소를 조회해서 로그인 시 보관한 세션 정보를 사용한다.

서블릿 HTTP 세션

서블릿이 제공하는 HttpSession을 사용하면, 추적 불가능한 랜덤값을 가진 쿠키가 생성된다.

// 세션이 있으면 있는 세션 반환, 없으면 신규 세션 생성
HttpSession session = request.getSession();
// 세션에 로그인 회원 정보 보관
session.setAttribute("loginMember", memberId);

// 로그아웃 (세션 만료)
session.invalidate();

서블릿이 제공하는 HttpSession을 통해 session을 생성하고, "loginMember"라는 이름으로 memberId값을 session에 저장한다.

request.getSession(true)
// 세션이 있으면 기존 세션 반환
// 세션이 없으면 새로운 세션 생성해서 반환

request.getSession(false)
// 세션이 있으면 기존 세션 반환
// 세션이 없으면 새로운 세셩 생성 X, null 반환

세션 종료 시점

application.properties 파일에 server.servlet.session.timeout=60 설정을 해주면 60초 후에 세션이 만료된다.
값은 초 단위이며, 기본 설정은 30분이다.

profile
나만 읽을 수 있는 블로그

0개의 댓글