[Web] Token based Authentication
토큰 기반 인증 (Token based Authentication)
모던 웹서비스에서 정말 많이 사용됨. API를 사용하는 웹서비스를 개발한다면, 토큰을 사용하여 유저들의 인증작업을 처리하는 것이 가장 좋은 방법.
특징
Statelss Server
Stateful Server란?
Client에게 요청을 받을 때마다, Client의 상태를 계속해서 유지하고, 이 정보를 서비스 제공에 이용함. ex) 세션을 유지하는 웹 서버
유저가 로그인을 하면, 세션에 로그인이 되었다고 저장을 해두고, 서비스를 제공 할 때에 그 데이터를 사용함. 세션은 Server 메모리에 담거나, DB에 담을 떄도 있음.
Stateless Server란?
상태를 유지 하지 않음.
상태 정보를 저장하지 않으면, Server는 Client측에서 들어오는 요청만으로만 작업을 처리함. 이렇게 상태가 없는 경우 Client와 Server의 연결고리가 없기 때문에, 서버의 확장성(Sclability)가 높아짐.
Mobile Application에 적합
만약, Android/IOS 모바일 어플리케이션을 개발 한다면, 안전한 API를 만들기 위해선 쿠키같은 인증시스템은 이상적이지 않다.
토큰 기반 인증을 도입하면 더욱 간단하게 번거로움을 해결할 수 있다.
인증정보를 다른 어플리케이션으로 전달
대표적인 예제로 OAuth가 있다. 페이스북/구글 같은 소셜 계정을 이용하여 다른 웹서비스에서도 로그인 할 수 있게 함.
보안
토큰 기반 인증 시스템을 사용하여 어플리케이션의 보안을 높일 수 있다. 단, 토큰 기반을 사용한다고해서 무조건 해킹의 위험에서 벗어나는건 아니다.
왜 토큰을 사용하게 되었을까?
서버 기반 인증 (기존)
기존 인증 시스템에서는 서버 측에서 유저들의 정보를 기억하고 있어야한다.
이 세션을 유지하기 위해서는 여러가지 방법이 사용된다.
메모리, 디스크, 데이터베이스 시스템에 담음.
하지만, 웹/모바일 웹 어플리케이션들이 커지면서 이런 인증 시스템은 문제를 보이기 시작함. 예를 들어, 서버를 확장하기가 어려움.
서버 기반 인증의 문제점
세션 세션의 경우 대부분 메모리에 저장하는데, 로그인 중인 유저의 수가 늘어난다면, 서버 RAM이 과부하가 됨. 이를 피하기 위해, 세션을 데이터베이스에 시스템을 저장하는 방식도 있지만, 이 또한 유저의 수가 많으면 데이터베이스 성능에 무리를 줄 수 있다.
확장성 세션을 사용하면 서버를 확장하는 것이 어려워 진다. ** 서버의 확장이란, 단순히 서버의 사양을 업그레이드 하는 것이 아니라, 더 많은 트래픽을 감당하기 위하여 여러개의 프로세스를 돌리거나, 여러 대의 서버 컴퓨터를 추가 하는 것을 의미함.
세션을 사용하면서 분산된 시스템을 설계하는 건 불가능 한 것은 아니지만, 과정이 매우 복잡해진다.
CORS Cross-Origin Resource Sharing 웹 어플리케이션에서 세션을 관리 할 때 자주 사용되는 쿠키는 단일 도메인 및 서브 도메인에서만 작동하도록 되어있다.
따라서, 쿠키를 여러 도메인에서 관리하는 것은 번거롭다.
토큰 기반 시스템의 작동 원리
토큰 기반 시스템은 stateless 이다. 무상태, 즉 상태를 유지 하지 않는다. 이 시스템에서는 더 이상 유저의 인증 정보를 서버나 세션에 담아두지 않는다.
이 개념 하나만으로 위에서 말한 Stateful에서 발생하는 문제점이 해소된다.
세션이 존재하지 않으니, 서버를 손 쉽게 확장할 수 있다.
토큰 기반 시스템의 구현 방식은 시스템마다 크고 작은 차이가 있지만, 대략적으로 다음과 같다.
- Client가 ID, PASSWD를로 로그인을 한다.
- Server에서 해당 계정정보를 검증한다.
- 계정정보가 정확하다면, Server에서 Client에게 signed 토큰을 발급해준다. (signed는 정상적으로 발급된 토큰임을 증명하는 signature를 의미)
- Client는 전달받은 토큰을 저장해두고, Server에 요청을 할 때마다, 해당 토큰을 함께 서버에 전달한다.
- Server는 토큰을 검증하고, 요청에 응답한다.
** 웹서버에서 토큰을 서버에 전달 할 때에는, HTTP 요청의 헤더에 토큰값을 포함시켜서 전달한다.
장점
Stateless 이며 확장성(Scalability)이 있다.
토큰은 ClientSide에 저장하기 때문에 Stateless하며, 서버를 확장하기에 매우 적합한 환경을 제공한다. 만약 세션을 서버측에 저장하고 있고, 서버를 여러대를 사용하여 요청을 분산하였다면, 어떤 유저가 로그인 했을 땐, 그 유저는 처음 로그인했었던 그 서버에만 요청을 보내도록 설정을 해야한다.
하지만, 토큰을 사용한다면 어떤 서버로 요청이 들어가던 이제 상관이 없다.
보안성
Client가 서버에 요청을 보낼 때, 더 이상 쿠키를 전달하지 않음으로 쿠키를 사용함으로 인해 발생하는 취약점이 사라진다.
하지만, 토큰을 사용하는 환경에서도 취약점이 존재 할 수 있으니 언제나 취약점에 대비를 해야 한다.
Extensibility (확장성)
Scalability는 서버를 확장하는 의미인 반면, Extensibility는 로그인 정보가 사용되는 분야를 확장하는 것을 의미.
토큰을 사용하여 다른 서비스에서도 권한을 공유 할 수 있다. 토큰에 선택적인 권한만 부여하여 발급을 할 수 있다.
여러 플랫폼 및 도메인
어플리케이션과 서비스의 규모가 커지면, 여러 디바이스를 호환 시키고, 더 많은 종류의 서비스를 제공하게 된다.
토큰을 사용한다면, 그 어떤 디바이스에서도, 그 어떤 도메인에서도, 토큰만 유효하다면 요청이 정상적으로 처리 된다.
서버 측에서 어플리케이션의 응답부분에 다음 헤더만 포함시켜주면 된다.
Access-Control-Allow-Origin: *
웹 표준 기반
토큰 기반 인증 시스템의 구현체인 JWT 는 웹 표준 RFC 7519에 등록이 되어 있다.
따라서, 여러 환경에서 지원이 되며 수많은 회사의 인프라구조에서 사용되고 있다.
Tip
JWT는 토큰 유형
OAuth는 토큰을 발급하고 인증하는 방법을 설명하는 일종의 프레임워크
EX)
기존 OAuth에서 주로 사용하는 bearer 기반의 토큰 방식.
* Bearer token
리소스에 대한 액세스 권한을 부여받기 위해 제시해야 하는 유일한 작업이 토큰을 주는 것
{
"token_type":"bearer",
"access_token":"eyJ0eXAiOiJKV1QiLCJh",
"expires_in":20,
"refresh_token":"fdb8fdbecf1d03ce5e6125c067733c0d51de209c"
}
JWT는 토큰 자체에 유저 정보를 담아서 HTTP 헤더로 전달
사용자 인증 방식
- Basic
- OAuth 1.0a Bearer
- OAuth 2.0 Bearer
- JWT Bearer
- Digest
- HOBA
Basic
ID와 비밀번호를 base64 인코딩하는 방식.
base64는 별도의 key 없이도 복호화가 가능한 인코딩이므로, 안전하지 않다.
OAuth 1.0a
Bearer 인증 표준이 아니다. Bearer 스펙을 명시한 RFC 6750에는 큰 글씨로 ‘The OAuth 2.0 Authorization Framework’
OAuth 2.0
확장성이 높음 (SNS 연동) OAuth2.0은 자체 암호화를 지원하지 않기 때문에 HTTPS를 쓰는 것을 권고 (비용 발생) OAUTH 2.0방식으로 Bearer Token 생성
JWT
토큰의 유형 Authorization 헤더 사용, 디지털 방식(sign)된 토큰 사용
참고 문서
https://velopert.com/2350