토큰 인증이란,
서버가 클라이언트에게 토큰을 발급하고 발급 이후부터 모든 클라이언트는 서버에 요청을 보낼 때 요청 헤더에 토큰을 포함하여 요청을 보낸다. 서버는 클라이언트로부터 받은 토큰을 서버에서 제공한 토큰이 맞는지 검증하여 사용자 인증을 처리하고 응답하는 방식이다.
토큰은 유일하다.
토큰은 '클라이언트가 인증되었다'는 의미이다.
(출처: https://velopert.com/2350)
JWT(Json Web Token)는 말그대로 웹에서 사용되는 JSON 형식의 토큰에 대한 표준 규격이다.
인증에 필요한 정보들을 암호화시킨 JSON 토큰을 의미한다.
(= 인증에 필요한 정보들을 Token에 담아 암호화시켜 사용하는 토큰)
주로 사용자의 인증(authentication) 또는 인가(authorization) 정보를 서버와 클라이언트 간에 안전하게 주고 받기 위해서 사용된다.
JWT는 Base64로 인코딩이 되어 있어서 육안으로 보면
eyJ
로 시작하는 아주 긴 문자열이다.
Header, Payload, Signature
로 구성된다.
(출처: https://supertokens.com/blog/what-is-jwt)
Header
: 토큰의 유형과 암호화 알고리즘(해시 알고리즘)의 종류를 JSON 형태로 담겨 있다.Payload
: 사용자의 인증/인가 정보가 담겨있다.Signature
: Header, Payload가 비밀키로 서명되어 담겨있다.JWT 토큰은 웹에서 보통
Authorization
HTTP 헤더를Bearer <토큰>
의 형태로 설정하여 클라이언트에서 서버로 전송되며, 서버에서는 토큰에 포함되어 있는 서명(signature) 정보를 통해서 위변조 여부를 빠르게 검증할 수 있다.
(출처: https://www.vaadata.com/blog/jwt-tokens-and-security-working-principles-and-use-cases/)
Bearer <토큰>
의 형태로 설정하여 요청을 보낸다.이미 발행된 토큰에 대한 악용을 막기 위해서 Access Token과 Refresh Token을 함께 사용한다.
Access Token만 사용한다면 이를 탈취당했을 때 문제가 생긴다. 토큰이 만료되기 전 까지, 이를 부당하게 획득한 사람이 마음대로 정보에 접근 가능하기 때문이다. 이는 토큰에 유효기간을 부여함으로서 대응할 수 있다.
그렇다면 유효기간을 어떻게 설정해야 할까? 유효기간이 너무 짧다면, 사용자는 Token을 계속해서 새롭게 발급받아야 하는 불편함을 겪는다. 그렇다고 너무 길게 설정하면, 탈취당했을 때 취약해진다.
이에 대응하기 위한 것이 Refresh Token이다.
클라이언트가 아이디와 패스워드로 로그인 요청을 하는 상황을 살펴보자.
서버는 로그인을 성공시키면서 클라이언트에게 Access Token과 Refresh Token을 동시에 발급한다.
이 Refresh Token은 긴 유효기간을 가지면서, Access Token이 만료됐을 때 새로 재발급을 받을 수 있게 해준다.
만약, Access Token 이 만료되면, 클라이언트는 같이 발급된 Refresh Token 을 이용하여 서버에 Access Token 재발급을 요청한다.
Access Token, Refresh Token은 모두 JWT 이다.
Access Token: 접근
Refresh Token: 재발급Access Token의 유효기간은 5분, 1시간, 24시간 등 다양하지만, 1일을 넘지 않는게 일반적이다.
Refresh Token 은 약 2주.
- JWT은 서명(인증)이 목적이다. 즉, 진짜 목적은 정보 보호가 아닌, 위조 방지이다.
- 서명이 되어 있는 JWT는 서버에서만 유효성을 검증할 수 있지만, 그 안에 저장된 데이터는 누구나 쉽게 열람이 가능하다. 따라서, 민감한 정보는 JWT 토큰에 그대로 저장하지 않아야 한다.