본문 바로가기
개발

로그인 인증 방식 - 세션, 쿠키, 토큰 특징

by 플리트우드 2025. 1. 27.
 

Http프로토콜은 기본적으로 무상태성을 지닌다.

 

근데 로그인 상태를 유지하려면 어쩔 수 없이 유저를 식별할 수 있는 값을 클라이언트와 서버간 공유해야한다.

 

이를 위해 쿠키, 세션, 토큰 등 여러 방법을 쓸 수있는데, 먼저 쿠키의 동작 방식부터 알아본다.

 

 

 

쿠키

 

  • 쿠키 동작 방식
    1. 브라우저(클라이언트)가 서버에 요청을 보낸다.
    2. 서버는 클라이언트의 요청에 대한 응답을 작성할 때, 클라이언트 측에 저장하고 싶은 정보를 응답 헤더의 Set-Cookie에 담는다. (클라이언트에서 스크립트로 쿠키 세팅하는 방법도 있음)
      •  쿠키와 세션은 모두 키-값으로 구성된다 
    3. 이후 해당 클라이언트는 요청을 보낼 때, 저장된 쿠키를 요청 헤더의 Cookie에 담아 보낸다. 
  • 쿠키 특징 
    • 쿠키가 언제 어느 사이트로 전송되는지는 뒤에 보게 될 키의 속성에 따라 다르다.
    • 쿠키는 보안에 취약하다. 탈취해서 클라이언트인 척 할 수 있다.(https는 헤더까지 다 암호화 하긴 함)
    • 크롬, 사파리 같은 브라우저에는 쿠키를 관리하기 위한 전용 메모리가 있다. 보통 확인할 수 없게 되어있지만, 개발자 도구 > application 탭 > storage > cookies 항목에 들어가면 현재 사이트의 쿠키를 확인할 수 있다.

 

 

  • 쿠키의 종류
    • 쿠키는 만료시간 세팅여부에 따라 지속쿠키, 세션쿠키로 나뉜다.
      • 지속쿠키
        • 브라우저를 꺼도 만료기간까지 남아있다. Max-Age 또는 Expires 속성을 사용해 만료기간을 정한다.
      • 세션쿠키
        • 브라우저를 끄면 날라간다.
  • 쿠키의 속성
    • HttpOnly, Secure
      • 보안을 위해 HttpOnly(스크립트가 쿠키를 얻는 걸 금지), Secure(Https로만 전송) 속성을 준다.
    • SameSite
      • 하나의 웹사이트는 자원 로드, 공격(!) 등의 이유로 수많은 사이트로 요청을 보낼 수 있다.
      • A 사이트에서 구글 이미지를 인터넷을 통해 로드한다고 치자. 나는 며칠 전 구글에 로그인 했기 때문에 구글에 대한 쿠키를 가지고 있다. A사이트가 구글 이미지를 로드하기 위해 구글에 Https 요청을 보낸다. 이때, 나의 구글 쿠키가 요청에 실릴 수 있냐 마냐를 정하는 속성이다. 실릴 수 없는 게 정상이다. 왜냐하면, A 사이트가 만약 피싱사이트일 때 내 쿠키를 가지고 구글에 비정상적인 요청을 보낼 수 있기 때문이다.
      • 옵션 : strict, lax, none
    • Path
      • /user 등, 특정한 요청에만 보내기
    • Domain
      • 미설정 시 쿠키를 세팅한 서버에 접속할 때만 보내진다. 하위 도메인에는 안 보낸다.
      • example.com으로 지정 시 example.com으로 들어갈 때 보내진다.하위 도메인으로도 보낸다.
      • sub.example.com로 지정 시 상위도메인인 example.com에 안 보내진다.

 

 

 

 

세션

 

 

세션은 기본적으로는 서버의 메모리에 존재한다. 스프링 어플리케이션의 경우 세션은 톰캣이 점유하는 메모리상에 있다.

 

  • 세션 동작방식 
    • http 요청이 오면, 톰캣이 세션ID를 생성해 이 요청과 바인딩한다. 해당 쓰레드는 필요시 HttpSession 객체를 통해 세션 정보를 알 수 있다.
  • 세션을 메모리로 관리하는 경우 문제점
    • 사용자 증가 시 관리해야되는 메모리가 늘어난다.
    • 서버 여러대인 경우 서버간 세션정보를 동기화해야하는 문제가 발생한다.
    • 서버 배포 시 메모리가 날라가서 로그인이 풀린다.
    • 위 문제점 때문에...
      • 세션을 메모리가 아니라 Redis 같은 외부 캐시 또는 DB로 관리하기도 한다.
      • 위 문제점 때문에 세션이 아니라 토큰 방식으로 많이 넘어간 추세다.
  • 세션이 삭제될 때
    • 서버가 세션을 언제 만료할지 정한다.
    • 클라이언트가 로그아웃 요청했을 때
    • ex) HttpSession.invalidate() 를 써서, 현재 HTTP 요청과 바인딩되어있는 세션ID를 지운다.
  • 세션 + 쿠키 인증 방식 
    • 서버에서 세션 ID라는 걸 생성해서 클라이언트에 쿠키로 가지고있거라~하고 던진다. 이렇게 클라이언트가 세션ID를 쿠키형태로 갖고있다가, 서버측 메모리에 저장된 세션을 통해 지속적으로 통신하는 데 쓴다.

 

 

 

 

 

토큰

 

 

  • 토큰은 쿠키,세션과 달리 서버쪽 저장소가 필요없다. 서버에서 로그인한 유저 정보에 기반한 토큰을 발급만 해주고, 그 다음부터는 클라이언트가 보내는 토큰을 복호화해서 검증만 하면 되기 때문이다. 근데 토큰은 보안을 위해 변경주기를 관리해줘야 하고, 유효기간이 너무 짧으면 로그인이 풀릴 때마다 유저 입장에서 불편하다. 그래서 취약점을 보완하기 위해 여러가지 방식이 나온 상황이다.