대표적인 토큰 기반 인증기술로는 JWT 가 있습니다.
JWT (JSON Web Token)
데이터 전송에 사용하는 대표적인 토큰기반 인증기술로, JSON 형식으로 저장한 정보(payload)를 암호화(서명)하여 전송합니다.
클라이언트가 서버에 요청을 보낼때 인증정보를 암호화된 JWT 토큰으로 제공하고, 서버는 이 토큰을 검증하여 인증정보를 확인할 수 있습니다.
JWT의 구성요소
JWT는 어떻게 토큰을 암호화하고 이를 검증하는 지 알아봅시다
JWT 기술로 만든 토큰은 보통 다음과 같은 형식의 문자열로 이루어집니다
여기에서 점(.)이 찍힌 부분을 기준으로 헤더(Header) , 페이로드(Payload), 시그니쳐(Signiture) 이렇게 3부분으로 나뉩니다
헤더(Header)
가장 앞에 위치한 헤더에는 마치 http의 헤더처럼 해당 토큰 자체를 설명하는 데이터가 담겨있습니다
JSON 객체로 토큰의 종류, 시그니쳐를 만들때 사용한 알고리즘을 담고, 이를 base64 방식으로 인코딩한 문자열입니다
{
"alg": "HS256",
"typ": "JWT"
}
페이로드(Payload)
가운데 payload는 http의 payload와 마찬가지로, 전달하려는 내용물을 담고 있는 부분입니다
JSON 객체로 유저정보 or 접근권한에 대한 정보를 담고, 이를 base64로 인코딩한 문자열입니다
(base64방식은 쉽게 디코딩할 수 있기 때문에 너무 중요한 정보는 담지 않는 것이 좋습니다)
{
"sub": "someInformation",
"name": "phillip",
"iat": 151623391
}
시그니쳐(Signiture)
마지막으로 시그니쳐는 토큰의 무결성(정확한 데이터 유지)을 확인할 수 있는 부분인데요
헤더와 페이로드가 완성되었다면, 이를 서버의 비밀키(암호화에 추가할 salt)와 헤더에 적은 알고리즘을 사용해 해싱한 문자열입니다
이를 통해 발급된 토큰이 위조된 것인지 아닌지를 확인할 수 있습니다
만약 클라이언트에서 디코딩이 쉬운 페이로드를 해독하고, 여기에 담긴 유저권한 or 유저정보를 위조해 서버에 요청을 보내도
서버의 비밀키를 모르는 이상, 이에 대응하는 시그니쳐 값을 만들 수 없다!
HMACSHA256(base64UrlEncode(header) + '.' + base64UrlEncode(payload), secret);
하지만, 만약 토큰이 위조된 것이 아니라, 토큰 자체가 제 3자에 의해 탈취된다면 어떻게 할까요?
토큰기반 인증또한, 취약점이 존재합니다
토큰기반 인증방식의 한계
1. 무상태성
앞서 토큰기반 인증의 장점으로 다루었던 무상태성이 단점이 될 수도 있다
세션과 달리 토큰방식에서는 서버가 인증상태를 관리하고 있지 않다
그래서 특정 서비스에서는 토큰인증방식이 적절하지 않을 수 있다
예를 들어, 온라인 강의나 OTT 서비스와 같이 동시접속을 막거나 디바이스의 로그아웃을 거는 기능이 필요할 때는 세션기반 인증이 적절합니다
또한, 토큰은 클라이언트에 저장되기 때문에 만약 제 3자가 토큰을 탈취해 인증을 보내더라도, 서버가 이를 강제로 로그아웃 시킬 수 없기 때문에 해당 코튼이 만료되기 전까지, 사용자로 가장해 제 3자가 계속해서 요청을 보낼 수 있다
2. 유효기간
강제만료가 불가능하기 때문에 토큰의 유효기간을 짧게 설정할 수 있지만, 제 3자가 아닌 일반 사용자의 경우 토큰이 만료될때마다 새롭게 로그인을 진행해야 하기 때문에, 사용자 경험이 떨어진다
유효기간을 늘리면 사용자 경험은 좋을 수 있지만, 토큰을 탈취하려는 해커가 있다면 보안에는 취약하게 되겠죠
이를 보완하기 위해, 뒤에 다룰 액세스 토큰과 리프레시 토큰, 2가지 토큰을 사용할 수도 있다
3. 토큰의 크기
토큰에 인증정보 뿐만 아니라 권한정보 등과 같은 다양한 데이터를 담을 수 있지만, 너무 많은 정보를 담을 경우 토큰의 크기 또한 커진다
따라서 네트워크 비용 문제가 생길 수 있다
토큰인증 방식의 한계점을 개선하기 위한 대표적인 기술로는 액세스 토큰(Access Token) 과 리프레시 토큰(Refresh Token)이 있다
이들은 토큰의 짧은 만료기간으로 인해 불편한 사용자 경험을 개선한다
액세스 토큰(Access Token)
말그대로 서버에 접근하기 위한 토큰으로, 앞서 다룬 인증 토큰과 비슷한 역할을 한다
보통 보안을 위해 24시간 정도의 짧은 유효기간이 설정되어 있다
리프레시 토큰(Refresh Token)
액세스 토큰이 만료되었을때 새로운 액세스 토큰을 발급해주는 토큰이다
그래서 7일 정도로 액세스 토큰보다 유효기간이 길다
이렇게 두 가지의 각기 다른 토큰을 사용하는 경우, 액세스 토큰이 만료되더라도 리프레시 토큰의 유효기간이 남아있다면 사용자는 다시 로그인을 할 필요 없이 지속해서 인증 상태를 유지할 수 있다.
물론 리프레시 토큰의 도입도 모든 문제를 해결해주진 않는다. 리프레시 토큰은 긴 유효 기간을 가지고 있어 해당 토큰마저 탈취된다면 토큰의 긴 유효 기간 동안 악의적인 유저가 계속해서 액세스 토큰을 생성하고 사용자의 정보를 해킹할 수도 있기 때문이다. 이를 대비하기 위해 리프레시 토큰을 세션처럼 서버에 저장하고 이에 대한 상태를 관리하기도 한다.
'Web system' 카테고리의 다른 글
ngrok을 통해 서버요청, 경고메세지 무시 (0) | 2023.07.16 |
---|---|
json server 명령어 (0) | 2023.06.23 |
세션(Session)과 토큰(Token) 의 차이점 (3) | 2023.06.17 |
HTTPS 암호화방식 (0) | 2023.05.03 |
네트워크 계층모델 (OSI 7계층 모델, TCP/IP 4계층 모델) (0) | 2023.05.01 |