웹 환경에서 사용자와 시스템 간에 데이터를 교환하기 위해 HTTP 방식을 사용합니다. HTTP 통신은 요청과 응답에 의해 동작하며, HTTP의 특징 중 가장 중요한 특징은 바로 Stateless 입니다. 문자 그대로 번역하면 State(상태) + less(없음) 을 의미합니다.
각각의 HTTP 통신(요청/응답)은 독립적 이기 때문에 과거의 통신(요청/응답)에 대한 내용을 전혀 알지 못 합니다. 이전의 상태를 전혀 알지 못 한다는 것은 무엇을 의미할까요?
매 통신마다 필요한 모든 정보를 담아서 요청을 보내야 합니다. 비유를 하자면, 마치 이미 자기소개를 한 사람에게 계속해서 똑같은 내용으로 자기소개를 해야하는 것과 같습니다.
따라서, 만약 로그인 후 상품 구매나 개인정보 수정 같이 여러번의 통신(요청/응답)의 진행 과정에서 연속된 데이터 처리가 필요한 경우에 Stateless의 특징에 따라 매번 로그인을 위한 인증정보를 같이 보내주어야 합니다.
위와 같은 불편함을 없애고자 일부 정보에 대해서 Stateful 상태를 유지할 필요가 있습니다. 이를 위해서 Session과 Cookie 또는 Token 같은 기술을 사용할 수 있습니다.
Session based Authentication
session 과 cookie의 차이에 대해 알아본 후 authentication에 대해 알아보도록 하겠습니다.
Session
동일한 클라이언트(사용자)가 브라우저를 통해 웹 서버에 접속한 시점으로부터 브라우저를 종료하여 연결을 끝내는 시점 동안에 들어오는 일련의 Request를 하나의 상태로 보고, 그 상태를 일정하게 유지하여 클라이언트와 웹 서버가 논리적으로 연결된 상태를 뜻합니다.
서버는 Session에 대한 정보를 저장하고 클라이언트에게는 Sesssion을 구분할 수 있는 ID를 부여하는데 이것을 Session ID라고 합니다.
클라이언트 Request를 보낼 때 해당 Session ID를 함께 보냄으로써, 클라이언트의 상태를 확인 할 수 있습니다.
Cookie
Cookie는 클라이언트의 컴퓨터에 저장되는 데이터 파일입니다. Cookie에는 이름, 값, 만료 날짜/시간(저장기간), 경로 정보 등으로 구성이 되어있습니다. Cookie는 하나의 도메인 당 20개를 가질 수 있으며, 1개 당 4Kbyte를 넘길 수 없다는 특징을 가지고 있습니다.
서버에서는 HTTP Response Header에 Set-Cookie 속성을 이용하여 클라이언트에 Cookie를 제공하여 저장하게 하고, 클라언트는 HTTP Request에 저장된 Cookie를 함께 전달하여 이전의 통신에서 사용된 정보들을 파악할 수 있습니다.
예를 들어 장바구니 기능 같은 경우 과거에는 로그인을 해야지만 사용할 수 있는데, 최근에는 Cookie를 이용하여 로그인을 하지 않은 상태로 장바구니에 상품을 담을 수 있게 되었습니다.
또한 Cookie를 통해 사용자별로 다른 정보를 표시하는 것이 가능하고, 사용자의 행동과 패턴을 분석할 수 있기 때문에 최근들어 더욱 중요한 개념이 되었습니다.
Session 기반 인증
사용자가 로그인을 하기 위해 인증 정보를 가지고 인증 과정을 요청 합니다.
인증이 완료 되면 사용자의 Session 정보를 서버의 메모리에 저장 후 해당 Session을 식별할 수 있는 Session ID 발급 합니다.
발급한 Session ID가 Cookie에 저장 될 수 있도록 HTTP Response Header의 Set-Cookie 속성을 이용하여 사용자에게 전달 합니다.
전달받은 Session ID는 브라우저의 Cookie에 저장 되고, Request를 서버에 보낼 때 함께 전달 됩니다.
서버는 사용자가 보낸 Session ID 와 서버 메모리에서 관리하고 있는 Session ID를 비교하여 Verification을 수행 후 권한을 인가 합니다.
장점
- Session ID 자체에는 유의미한 개인정보를 담고 있지 않습니다.
- 서버에서 정보를 관리하기 때문에 데이터의 손상 우려에 대해 상대적으로 안전 합니다.
- 서버에서 상태를 유지하고 있으므로, 사용자의 로그인 여부 확인이 쉽고, 경우에 따라서 강제 로그아웃 등의 제재를 가할 수 있습니다.
단점
- 서버에서 모든 사용자의 상태를 관리해야 되므로 사용자의 수가 증가 할 수록 서버에 가해지는 부하가 증가합니다.
- 사용자가 증가하여 서버의 Scale Out을 해야 할 때 Session의 관리가 어려워 집니다.
- 모바일 기기와 브라우저에서 공동 사용 할 때 중복 로그인 처리가 되지 않는 문제 등 신경 써줘야 할 부분 들이 증가합니다.
Token 기반 인증
일반적으로 사용되는 Token의 사전적 의미를 찾아보면 버스 요금이나 자동판매기 등에 사용하기 위하여 상인, 회사 등에서 발행한 동전 모양의 주조물 이라고 나와있습니다. 웹에서의 토큰도 이와 비슷한 의미를 가지고 있습니다. 일상에서는 Token을 가지고 있으면 버스를 탈 권리, 도는 자동판매기에서 상품을 구매할 권리를 가지고 있다면, 웹에서는 Token을 가지고 있으면 해당 서비스를 이용할 수 있는 권리가 있다고 생각 할 수 있습니다.
조금 더 자세히 이야기해 보면 Token은 제한된 리소스에 대해 일정 기간 동안 접근 할 수 있는 권한을 캡슐화 한 것입니다. Token은 일반적으로 의미를 알 수 없는 임의의 문자열 형태로 사용자에게 발급 합니다. 또한, 제한된 리소스에 대한 접근 권한을 캡슐화 할 뿐만 아니라 접근 할 수 있는 리소스의 범위와 접근 가능한 기간을 통제 할 수 있습니다.
사용자가 로그인을 하기 위해 인증 정보를 가지고 인증 과정을 요청 합니다.
인증이 완료 되면 서버의 메모리에 Session을 저장하는 대신에 사용자의 식별 정보를 가지고 있는 Token을 발급합니다.
발급한 Token은 Response의 Body에 담아 사용자에게 전달합니다.
사용자는 발급된 Token을 local storage에 저장 합니다.
사용자는 Request를 할 때마다 저장된 Token을 Header 에 포함시켜 서버로 보냅니다.
서버는 사용자로부터 전달받은 Header의 Token 정보를 Verification 한 뒤, 해당 유저에 권한을 인가 합니다.
장점
- Token을 사용자 측에서 저장하므로 서버의 메모리나 DB 등의 부담이 없습니다.
- 사용자의 상태 정보를 서버에서 관리하지 않기 때문에 서버의 Scale Out에 용이 합니다.
- 모바일과 브라우저의 멀티 환경에서 사용이 용이 합니다.
- Token의 만료 시간을 짧게 설정하여 안정성을 높일 수 있습니다.
- CORS 방식을 사용하기 용이 합니다.
단점
- 서버에서 사용자의 상태를 저장하고 있지 않기 때문에 사용자의 로그인 여부 확인, 경우에 따른 강제 로그웃 등의 제재를 가하기 어렵습니다.
- 사용자가 임의로 토큰을 수정하거나 구조가 변경되게 되면 서버에서 확인할 수가 없습니다.
- Payload 부분에 사용자 식별을 위한 여러 정보들이 포함 되어 있어 Session Id의 길이보다 길어져 HTTP request 전송 데이터의 크기가 증가 합니다.
- XSS 공격에 취약하여 Payload에 민감한 정보를 포함하는 경우 위험할 수 있습니다.
오늘은 session 기반 인증과 token 기반 인증을 알아봤습니다. 서로 장단점이 있지만 둘다 알아 놓는 것이 좋을 것 같다고 생각되네요
부록
CSRF (Cross site request forgery) - 사이트 간 요청 위조
토큰을 사용하면 csrf 공격을 방지하는데 도움이 된다고 합니다.
'코딩 개발' 카테고리의 다른 글
Bcrypt & JWT (0) | 2022.11.07 |
---|---|
암호화의 종류 (0) | 2022.11.07 |
인증과 인가 (0) | 2022.11.06 |
API Documentation (0) | 2022.11.06 |
MYSQL - query 문은 어려워 (table 1칸에 여러개의 값) (0) | 2022.11.04 |