세션 기반 인증
애플리케이션 통신에 가장 많이 쓰이는 통신 방법은 HTTP입니다.
하지만 HTTP는 무상태성(Stateleses) 프로토콜로 누가 요청을 했는지, 인증된 클라이언트인지 확인이 불가능한데 이를 해결하기 위해 나온 방법이 서버 측에 클라이언트의 접속 상태를 저장
하는 세션 기반의 인증입니다.
이미지 출처: https://blog.lgcns.com/2687
서버 기반 인증의 문제점
- 세션 : 세션이란 유저가 인증을 할 때, 서버에 저장하는것으로 대부분의 경우엔 메모리에 이를 저장하는데, 로그인의 유저가 늘어나면 램의 과부화 발생. 이를 해결하기 위해 세션을 데이터베이스에 저장하는 방식도 있지만 이 또한 유저의 수가 많으면 DB에 무리를 줄 수 있음
- 확장성 : 세션을 사용하면 서버의 확장이 어려워짐, 세션을 사용하면서 분산된 시스템을 설계하는건 불가능한것은 아니지만 과정이 매우 복잡해짐
- CORS : 웹 어플리케이션에서 세션을 관리 할 때 자주 사용되는 쿠키는 단일 도메인 및 서브 도메인에서만 작동하도록 설계되어 있어 쿠키를 여러 도메인에서 관리하는것은 번거로움
토큰 기반 인증
토큰은 사용자 인증을 위한 정보를 서명한 것으로, 세션 기반의 인증은 클라이언트의 상태를 서버 내에 저장하며 요청 마다 세션 스토리지에 저장된 유효한 세션인지 확인하지만 토큰 기반의 인증 방법은 토큰에 사용자 인증을 위한 정보가 담겨있기 때문에 서버에 사용자 정보를 저장하지 않고
, 전달받은 토큰의 서명과 데이터를 검증하는 것 만으로 인증이 가능함
이미지 출처: https://blog.lgcns.com/2687
토큰에는 암호화 방식과 타입 등을 나타내는 헤더, 전송할 데이터가 담긴 페이로드, 토큰 검증을 위한 서명을 각각 인코딩(해싱)한 값이 포함되어 있습니다.
데이터가 인코딩이 되어있긴 하지만 누구나 디코딩을 할 수 있어서 데이터 유출에 대한 피해가 있을 수 있지만 서명 필드는 헤더와 페이로드를 통해 만들어지기 때문에 데이터 변조 후 재전송하는 것을 막을 수 있습니다.
토큰 기반 인증의 장단점
장점
- 헤더와 페이로드를 가지고 서명 필드를 생성하므로 데이터 변조 후 재전송을 막을 수 있습니다.
- stateless 서버를 만들 수 있습니다.
- 모바일 어플리케이션에서도 잘 동작합니다.
- 인증정보를 다른 웹서비스에 전송할 수 있습니다. (OAuth)
단점
- 여전히 누구나 디코딩이 가능하므로 데이터 유출이 발생할 수 있습니다.
- 토큰을 탈취당할 경우, 대처하기 어렵다. (유효기간을 기다리거나 token refresh를 해야한다)
- JWT의 경우, 토큰의 길이가 길기 때문에 요청이 많아질수록 서버 자원의 낭비가 많아진다.
인증 타입
일반적으로 토큰은 요청 헤더의 Authorization 필드에 담아져 보내집니다. bearer의 형식은 type에 해당하며 다양한 종류의 토큰을 처리하기 위해 전송받은 type에 따라 토큰을 다르게 처리합니다.
Authorization: <type> <credentials>
Basic
= 사용자 아이디와 암호를 Base64로 인코딩한 값을 토큰으로 사용한다. (RFC 7617)
Bearer
= JWT 혹은 OAuth에 대한 토큰을 사용한다. (RFC 6750)
Digest
= 서버에서 난수 데이터 문자열을 클라이언트에 보낸다. 클라이언트는 사용자 정보와 nonce를 포함하는 해시값을 사용하여 응답한다 (RFC 7616)
HOBA
= 전자 서명 기반 인증 (RFC 7486)
Mutaul
= 암호를 이용한 클라이언트-서버 상호 인증 (draft-ietf-httpauth-mutual)
AWS4-HMAC-SHA256
= AWS 전자 서명 기반 인증