(00) :: Authentication and Authorization
Authentication
인증(Authentication)이란 해당 Service의 User가 맞는지 확인하는 과정입니다.
Authorization
인가(Authorization)이란 어떤 수준의 Service를 사용할 것인지 확인하는 과정입니다.
Example
기차에 탑승하는 과정을 예로 들어보겠습니다.
기차 티켓이 있는지 확인하는 과정은 인증 과정이고, 기차 티켓이 1등급인지 2등급인지 구분하는 과정을 인가 과정입니다.
(01) :: Cookie
Why we do need Cookie?
HTTP 프로토콜은 Stateless 이라는 특성을 가지고 있습니다.
때문에, 사용자의 상태를 저장(유지)할 수 없습니다.
다른 웹 페이지로 이동하거나, 브라우저를 껐다 키면 모든 데이터가 사라지는 것입니다.
What is the Cookie?
쿠키(Cookie)는 서버가 사용자의 웹 브라우저에 저장해 놓는 작은 데이터입니다.
브라우저는 그 데이터들을 저장해 놓았다가, 서버에서 요청하면 해당 데이터를 함께 전달하여 요청합니다.
이를 통해 서버는 해당 사용자가 인증된 사용자인지 혹은 인가된 사용자인지 판단할 수 있습니다.
Kind of Cookie
쿠키는 크게 세션 쿠키(Session Cookie)와 지속 쿠키(Persistent Cookie)로 나눌 수 있습니다.
Session Cookie
세션 쿠키는 현재 세션이 종료될 때 자동으로 삭제가 됩니다.
이때, 세션이 종료되는 시점을 정의하는 것은 웹 브라우저의 역할입니다.
특정 웹 브라우저들은 세션을 복원하여 세션 쿠키가 무기한 존재할 수 있게 합니다.
Persistent Cookie
지속 쿠키는 서버의 Expires 또는 Max-Age 속성에 의해 명시된 날짜에 삭제가 됩니다.
(02) :: JWT
What is the JWT?
JWT(Json Web Token)은 정보를 담고 있는 토큰으로 사인된 토큰을 통해 해당 토큰이 유효한지 검증합니다.
때문에, 별도로 Token을 DB에 저장할 필요가 없습니다.
JWT Structure
JWT는 구분자인 점(.)을 이용하여 3가지의 부분으로 구성되어 있습니다.
Header.Payload.Signature
Header
토큰의 타입과 토큰 해싱 알고리즘에 대한 정보가 담겨있습니다.
Payload
사용자의 정보나 데이터가 담겨있습니다.
서버 측에서 사용자에게 이 토큰을 통해 공개되기 원하는 내용만 담아야 합니다.
주된 내용은 다음과 같으며, JSON 형태로 반환합니다.
- issuer : 누가 누구에 발급했는지
- expires : 토큰의 유효기간
- username: 사용자의 이름
- role: 사용자의 역할
Signature
Header + Payload + 서버에 저장되어 있는 Secret Key을 Header의 해싱 알고리즘을 이용해 서명한 값이 Signature 부분의 값이다.
(03) :: Authentication Process
두 인증 방식의 가장 큰 차이점은 사용자의 정보를 서버에 저장하는지의 여부입니다.
Session Based Authentication Process
- 사용자가 사용자 정보를 전달하여 로그인에 성공하면 사용자를 위한 세션을 만들고, 세션 데이터를 서버에 저장합니다.
- 서버에서 클라이언트 측으로 세션 ID가 담긴 쿠키를 보내고, 이는 브라우저 쿠키에 저장됩니다.
- 클라이언트는 해당 사이트에 대한 인가가 필요한 모든 요청에 세션 ID를 쿠키에 담아 서버에 전송합니다.
- 서버는 클라이언트가 보낸 세션 ID와 서버 측에 저장된 세션 ID를 비교하여 유효성 검증 및 인가 수준을 판단하여 해당 요청에 대해 클라이언트에게 응답합니다.
- 사용자가 웹 사이트에서 로그아웃하면 해당 세션 데이터가 서버 측에서 삭제되며, 브라우저에 저장되어 있는 세션 ID는 쓸모가 없어집니다.
Session 방식을 이용하면 인가가 필요한 요청이 있을 때마다 쿠키에 담긴 세션 ID를 전달받아 서버에 저장되어 있는 세션 ID와 비교해야 합니다.
또한, 사용자가 늘어날수록 세션 ID를 저장할 공간을 더 확보해야 합니다.
대신 사용자의 로그인 상태를 모두 저장하고 있기 때문에 세션을 삭제하여 강제 로그아웃을 시키거나, 접속 인원을 제한을 두는 등 다방면으로 활용할 수 있습니다.
Token Based Authentication Process
- 사용자가 로그인에 성공하면 서버에서는 JWT형태의 암호화된 토큰을 발급(생성)한다.
- 생성된 토큰(암호화된 JWT)을 클라이언트에 보낸다.
- 클라이언트가 해당 토큰을 받으면 일반적으로 클라이언트 측의 localStorage에 저장하고, 사용자가 로그아웃하면 토큰이 클라이언트 측(localStorage)에서 삭제된다.
- 사용자가 인증 및 인가가 필요한 요청을 할 때 header에 발급받은 토큰을 담아서 보낸다.
- 서버 측에서는 요청에 토큰 값이 실려오면, JWT의 header와 payload값을 서버측에 감춰둔 secret key와 함께 돌려서 계산된 결괏값이 Signature 값과 일치하는 결과가 나오는지 확인한다.
- 서명 값과 계산 값이 일치하고, 유효기간도 지나지 않았다면 해당 사용자는 이후 모든 요청에 대해 로그인된 회원으로 권한을 인가(Authorization)한다.
JWT 방식은 세션 방식과 다르게 서버에 데이터를 저장하지 않아 별도로 공간을 확보할 필요는 없습니다.
그러나, 탈취 당한 토큰의 제어권을 가지지 못해 비교적 보안성이 떨어집니다.
이를 보완하기 위해, Access Token과 Refresh Token을 적절히 운용해야 합니다.
Access Token의 경우 토큰 만료 시간을 짧게 잡아 탈취 당하더라도 만료되도록 설정하는 것이 중요합니다.
Refresh Token의 경우 기간을 보통 2주 정도로 잡아 사용자가 현재 작업을 진행 중이면 다시 토큰을 받을 수 있도록 합니다.
Refresh Token은 서버 측 DB에 저장되며, 사용자의 요청에 담겨온 Refresh 토큰과 비교하여 유효성 검증을 수행한 뒤에만 Access Token을 발급합니다.
만약 Refresh Token이 탈취되는 경우 DB 상에서 Refresh 토큰을 삭제하여 즉시 만료 시킬 수 있습니다.
다만, Access Token이 만료되기 전까지 취약성이 노출됩니다.