저번 블로그에서 다룬 세션의 서버의 너무 많은 메모리를 차지하는 단점을 보안한 방법이 토큰 기반 인증이다.
세션 기반 인증은 유저의 정보를 서버에 담기 때문에, 유저가 서버에게 제한된 정보를 요청할 때 마다 세션 값과 일치하는지 확인한다.
데이터베이스를 탐색해야 함으로 서버에 너무 부담이 큰 방법인 것이다.
그래서 나오게 된 것이 토큰 기반 인증이다.
토큰의 가장 큰 장점은 무상태성(stateless)과 확장성이다.
토큰은 클라이언트에 저장하기 때문에 stateless하고, 서버를 확장해도 전혀 문제가 되지 않는다.
세션방식을 생각해 보면, 세션은 서버쪽에 저장을 하고 있어서 만약 유저가 로그인 했을때, 처음 서버가 세션을 저장하고 있다면 로그인이 잘 되지만, 다른 서버에 저장되어 있는 자료의 접근할 경우 그 서버가 세션을 저장하고 있지 않으면 인가되지 않은 유저라고 판단하고 로그아웃이 될 것이다.
위 같은 특징으로 인해 토큰은 토큰을 사용하려는 서버에서 필수적으로 만들지 않아도 된다.
그래서 토큰을 발행한 특정 사이트 뿐만 아니라 다른 사이트에서도 그 토큰을 이용해서 사용할 수 있다.
토큰 기반 인증에서 가장 많이 사용되는 방식은 JWT방식이다.
JWT는 위와같은 구조를 가지고 있다.
typ은 토큰의 타입으로 'JWT'토큰이므로 그림과 같이 JWT가 들어가는 것이다.
그리고 alg은 알고리즘의 약자로 'Signature'를 만드는데 사용될 알고리즘이 지정된다.
그림에서는 HS256 암호화 방식을 지정한 것이다.
페이로드는 Base64로 디코딩 하면 JSON형식으로 여러 정보가 들어있다.
이 토큰을 누가 누구한테 발급하는지, 토큰의 유효기간, 사용할 수 있는 권한 등이 포함되어있다.
서명값은 header와 payload를 헤더에서 선택한 알고리즘으로 암호화한 값이 포함되어 있다.
아래 그림은 쿠키방식과 토큰 방식의 차이를 그림으로 나타낸 것이다.
토큰 기반 인증의 흐름을 순서대로 써보자면
1. 유저가 아이디와 비밀번호로 로그인 수행
2. 서버측에서 해당정보 검증
3. 계정 정보가 정확하다면 서버측에서 유저에게 signed 토큰을 발급
4. 클라이언트는 토큰을 저장해 두고 요청마다 토큰을 서버에 함께 전달
5. 서버에서 토큰을 검증하고 요청에 대답
이와 같은 순서로 진행된다.