우디의 개발스터디

[네트워크] 서버 인증 방식 - 쿠키/세션, 토큰

by 개발자 우디

 

HTTP는 비연결성 및 무상태성이라는 특징을 가지고 있다. 따라서 클라이언트의 요청을 처리한 뒤 연결을 끊어버리기 때문에, 클라이언트의 상태 정보 및 현재 통신 상태가 남아있지 않는다.

그렇다면 왜 HTTP는 비연결성이라는 특성을 가지고 있을까?

우선 비연결성의 장점은 서버의 자원 낭비를 줄일 수 있다는 점이다. 예를 들어 만약 다수의 클라이언트가 서버와의 연결을 유지한다면 서버의 자원 낭비가 심해지고 성능의 저하를 야기할 수 있기 때문이다.

허나 비연결성은 클라이언트를 식별할 수 없다는 단점 또한 존재한다. 로그인을 하더라도 다음번 요청에서 해당 클라이언트를 식별할 수 있는 무언가가 없기 때문에, 계속 로그인을 해야 할 것이다. 참고로 이렇게되면 웹 브라우저(Ex.크롬)에서 새로고침을 누를 때마다 로그인을 해야한다.

이런 장점과 단점들을 보완하기 위해 CookieSession 그리고 토큰이라는 기술을 활용하게 된다.

 

쿠키 (Cookie)

쿠키(Cookie)란 클라이언트가 어떠한 웹사이트를 방문할 경우, 그 사이트가 사용되고 있는 서버를 통해 클라이언트의 브라우저에 설치되는 작은 기록 파일을 일컫는다. 간단히 말해 서버와 클라이언트가 대화하기 위한 수단이다.

서버는 클라이언트의 로그인 요청에 대한 응답을 작성할 때, 클라이언트 측에 저장하고 싶은 정보를 응답 헤더의 Set-Cookie에 담는다(쿠키는 Key-Value형식의 문자열이다.) 이후 해당 클라이언트는 요청을 보낼 때마다 매번 저장된 쿠키를 요청 헤더의 Cookie에 담아 보낸다. 서버는 쿠키에 담긴 정보를 바탕으로 해당 요청의 클라이언트가 누군지 식별할 수 있다.

 

쿠키의 특징

  • 브라우저가 서버와 연결이 되었을 때 브라우저에서 자동적으로 쿠키를 생성하고, response 할 때 쿠키를 담아서 보낸다.
  • 특정 호스트에서 생성된 쿠키는 이후 모든 요청마다 서버로 전송된다.
  • 요청 해더의 set-cookie 속성에 정보를 담을 수 있다.
  • 쿠키에 담긴 데이터는 브라우저에서 관리된다.
  • 이름, 값, 만료 날짜, 경로 정보로 구성된다.

 

쿠키의 단점

  • 보안에 취약하다. (요청 시 쿠키의 값을 그대로 보내어, 유출 및 조작당할 위험이 존재한다.)
  • 용량 제한이 있어, 많은 정보를 담을 수 없다.
  • 웹 브라우저마다 쿠키에 대한 지원 형태가 다르기에, 브라우저 간 공유가 불가능하다.
  • 쿠키의 사이즈가 커질수록 네트워크에 부하가 심해진다.

 

세션 (Session)

서버와 클라이언트의 연결이 활성화된 상태에서 활용되는 방식.

 

동작 과정

세션이란

세션은 비밀번호 등 클라이언트의 인증 정보를 쿠키가 아닌 서버 측에 저장하고 관리한다.

서버는 클라이언트의 로그인 요청에 대한 응답을 작성할 때, 인증 정보는 서버에 저장하고, 클라이언트 식별자인 JSESSIONID를 쿠키에 담는다. 이후 클라이언트는 요청을 보낼 때마다 JSESSIONID쿠키를 함께 보낸다. 그리하면 서버는 JSESSIONID의 유효성을 판별해 클라이언트를 식별한다.

 

동작 순서

  1. 사용자가 로그인 요청한다.
  2. 서버에서 계정 정보를 읽어 사용자를 확인 하고, 사용자의 고유한 ID를 부여하여 세션 저장소에 저장한 후, 이와 연결된 세션ID를 발급한다.
  3. 사용자는 서버에서 해당 세션ID를 받아 쿠키에 저장 한 후, 인증이 필요한 요청마다 쿠키를 헤더에 실어 보낸다.
  4. 서버는 쿠키를 받아 세션 저장소에서 대조 후 대응되는 정보를 가져온다.
  5. 인증이 완료 되고 서버는 사용자에 맞는 데이터를 보내준다.

 

세션의 특징

  • 클라이언트가 서버와 통신을 시작하면 서버는 해당 클라이언트에 대해 유일한 고유값인 세션 ID를 부여, 세션 스토리지에 해당 세션 ID 정보를 저장한다.
  • 클라이언트는 이 세션ID를 쿠키를 통해 기억한다.
  • 클라이언트가 추가로 어떤 요청을 보낼 때마다 헤더의 cookie에 세션 ID를 담아서 전송함.(식별을 위해)
  • 서버는 클라이언트가 보낸 요청의 쿠키에 담긴 세션ID와 세션 스토리지에 담긴 세션ID를 대조해 인증 상태를 판단함(즉, 세션과 쿠키는 완전히 분리된 개념이 아니며 세션은 쿠키를 기반으로 함)
  • 각 클라이언트마다 유니크한 세션 객체가 주어지고, 이 세션 객체에 데이터를 담아 관리할 수 도 있음(세션 객체가 자물쇠로 잠긴 상자라면 세션ID가 열쇠)
  • 세션을 사용하지 않고 쿠키만으로 어떤 데이터를 주고받는다면, 클라이언트는 이미 모든 데이터를 알고 있다는 것.

 

세션을 통한 인증의 장점

  • 서버가 클라이언트의 웹 브라우저에 의존하지 않아도 된다.
  • 쿠키를 포함한 요청이 외부에 노출되어도 세션 ID 자체는 유의미한 개인 정보를 담지 않는다.
  • 각 사용자마다 고유한 세션 ID가 발급되기 때문에, 요청이 들어올 때마다 회원 정보를 확인(로그인)할 필요 없다.

 

세션을 통한 인증의 단점

해커가 세션 ID를 중간에 탈취하여 클라이언트인 척 위장할 수 있다.

서버에서 세션 저장소를 사용하기 때문에, 요청이 많아지면 서버에 부하가 생긴다.

 

토큰 (Token)

JWT는 세션/쿠키와 함께 가장 대표적인 인증 수단이다. JWT(JSON Web Token)의 약자로 인증에 필요한 정보들을 암호화시킨 토큰을 뜻한다. 세션/쿠키 방법과 유사하게 사용자는 Access Token(JWT토큰)을 HTTP헤더에 실어 서버로 보낸다.

JWT(JSON Web Token)는 인증에 필요한 정보들을 암호화시킨 토큰이다.

 

 


JWT의 구조는 위 사진과 같이 세가지 문자열의 조합이다. 실제 디코딩된 JWT는 HeaderPayloadSignature로 이루어져 있다.

  • Header : 위 3가지 정보를 암호화할 방식(alg), 타입(type) 등
  • Payload : 서버에서 보낼 데이터. 일반적으로 유저의 고유 ID값, 유효기간
  • Verify Signature : Base64 방식으로 인코딩한 Header,payload 그리고 SECRET KEY를 더한 후 서명

 

토큰 액세스

 

토큰 인증 과정

  1. 클라이언트 로그인 요청이 들어오면, 서버는 검증 후 클라이언트 고유 ID등의 정보를 Payload에 담는다.
  2. 암호화할 비밀키를 사용해 Access Token(JWT)을 발급한다.
  3. 클라이언트는 전달받은 토큰을 저장해두고, 서버에 요청할 때마다 토큰을 요청 헤더 Authorization에 포함시켜 함께 전달한다.
  4. 서버는 토큰의 Signature 을 비밀키로 복호화한 다음, 위변조 여부 및 유효 기간 등을 확인한다.
  5. 유효한 토큰이라면 요청에 응답한다.

 

토큰의 장점

  • Header와 Payload를 가지고 Signature를 생성하므로 데이터 위변조를 막을 수 있다.
  • 인증 정보에 대한 별도의 저장소가 필요 없다. (I/O 처리 필요 없음)
  • JWT는 토큰에 대한 기본 정보와 전달할 정보 및 토큰이 검증됐음을 증명하는 서명 등 필요한 모든 정보를 자체적으로 지니고 있다.
  • 클라이언트의 인증 정보를 저장하는 세션과 다르게, 서버는 무상태(Stateless)가 된다.
  • 확장성이 우수하다.
  • 토큰 기반으로 다른 로그인 시스템에 접근 및 권한 공유가 가능하다. (토큰 서버 활용)
  • 토큰 기반으로 다른 로그인 시스템에 접근 및 권한 공유가 가능하다.
  • OAuth의 경우 Facebook, Google 등 소셜 계정을 이용해 다른 웹서비스에서도 로그인 할 수 있다.
  • 모바일 어플리케이션 환경에서도 잘 동작한다.

 

토큰의 단점

  • 쿠키, 세션과 다르게 JWT는 토큰의 길이가 길어, 인증 요청이 많을수록 네트워크 부하가 심해진다.
  • Payload 자체는 암호화되지 않기 때문에 유저의 중요한 정보는 담을 수 없다. (패스워드 등)
  • 토큰을 탈취당하면 대처하기 어렵다. 토큰은 한 번 발급되면 유효기간이 만료될 때까지 계속 사용이 가능하다.
  • 특정 사용자의 접속을 강제로 만료하기 어렵다. (쿠키/세션 기반 인증은 서버 단에서 쉽게 삭제할 수 있지만 토큰은 그게 안 됨)

 

이러한 단점을 보완하기 위한 토큰 전략들은 몇 가지가 있는데 그 중 기존의 Access Token의 유효기간을 짧게 하고 Refresh Token이라는 새로운 토큰을 발급해서 Access Token을 탈취 당해도 상대적으로 피해를 줄일 수 있는 방법이 있다.

 

Refresh Token

Access Token(JWT)를 통한 인증 방식의 문제는 제 3자에게 탈취당할 경우 보안에 취약하다는 점이다. 유효기간이 짧은 Token의 경우 그만큼 사용자는 로그인을 자주해서 새롭게 Token을 발급받아야 하므로 불편하다. 그러나 유효기간을 늘리자면, 토큰을 탈취당했을 때 보안에 더 취약해진다.

 

"그러면 유효기간을 짧게 하면서 더 좋은 방법은 없을까?" 라는 고민에 의해 탄생하게 된 것이 Refresh Token이다.

 

Refresh Token은 Access Token과 똑같은 형태의 JWT이다. 처음에 로그인을 완료 했을때 Access Token과 동시에 발급되는 Refresh Token은 긴 유효기간을 가지면서, Access Token이 만료됐을 때 새로 발급해주는 열쇠가 된다.

Access Token은 탈취 당하면 정보가 유출되는건 동일하다. 다만 유효기간이 짧기에 조금더 안전하다는 뜻이다.

 

Refresh Token의 휴효기간이 만료 됐다면, 사용자는 새로 로그인 해야한다. Refresh Token도 탈취될 가능성이 있기때문에 적절한 유효기간 설정이 필요하다.(보통 2주)

 

참고

https://velog.io/@kingth/%EC%84%9C%EB%B2%84-%EC%9D%B8%EC%A6%9D-%EB%B0%A9%EC%8B%9D%EC%84%B8%EC%85%98%EC%BF%A0%ED%82%A4-%ED%86%A0%ED%81%B0

https://velog.io/@kingth/%EC%84%9C%EB%B2%84-%EC%9D%B8%EC%A6%9D-%EB%B0%A9%EC%8B%9D%EC%84%B8%EC%85%98%EC%BF%A0%ED%82%A4-%ED%86%A0%ED%81%B0

https://tecoble.techcourse.co.kr/post/2021-05-22-cookie-session-jwt/

 

 

 

 

블로그의 정보

우디의 개발스터디

개발자 우디

활동하기