진행중인 미니 프로젝트를 하면서 무언가 찝찝함을 느꼈습니다.
클라이언트가 API를 통해 로그인하지만, 다음 요청을 보내면 서버는 누가 보냈는지 알 수 없습니다.주문을 하려면 계속 로그인을 시도해야 하는 악질 사이트네요.
클라이언트의 신원을 검증하는 것을 인증이라고 하고,
인증 후에 클라이언트가 어떤 자원에 접근할 수 있는지 확인하는 것을 인가라고 합니다.
이번 포스트에서는 인증 방식 중 하나인 JWT에 대해서 알아보겠습니다.
🔑 토큰 기반 인증
사용자를 인증하기 위해서 서버에서 인증 정보를 관리하는 것을 세션 기반 인증이라고 합니다.
이 방법은 사용자가 증가하면 유지해야 하는 정보가 많아지기 때문에 성능에 이슈가 생길 수 있습니다.
이를 극복하기 위해서 토큰 기반 인증을 눈 여겨 볼 수 있습니다.
토큰 기반 인증은 토큰을 발급하여 클라이언트에 저장하고, 이에 대한 위조를 판별하여 사용자를 인증합니다.
하지만, 토큰 자체를 탈취당하면 해당 사용자의 권한을 모두 뺏기는 거나 다름없다는 문제가 있습니다.
🔑 JWT의 기본 구조
JWT는 JSON Web Token의 약자로, 사용자의 정보를 JSON 객체로 전달하는 토큰입니다.
토큰은 xxxxx.yyyyy.zzzzz 이렇게 점을 기준으로 세 부분으로 구성되어 있습니다.
헤더는 토큰의 유형과 서명에 쓰이는 알고리즘이 적혀있는 JSON 객체입니다.
이 객체가 Base64Url로 인코딩되어 가장 첫 부분을 담당합니다.
{
"alg": "HS256",
"typ": "JWT"
}
// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
페이로드도 Base64Url로 인코딩되어 토큰의 두 번째를 담당합니다.
페이로드는 클레임을 포함하고 있습니다.
클레임이란 서버와 클라이언트가 주고받으며 사용할 정보를 의미합니다.
{
"sub": "1234567890",
"name": "Subin Cha",
"iat": 1516239022
}
// eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlN1YmluIENoYSIsImlhdCI6MTUxNjIzOTAyMn0
시그니처는 특정 알고리즘으로 인코딩된 헤더와 페이로드를 암호화한 문자열입니다.
암호화할 때 쓰인 비밀키를 모른다면 제 3자가 복호화할 수 없으므로, 토큰이 위조되었는지 판별할 수 있습니다.
HMACSHA256 (
base64UrlEncode(헤더) + "." +
base64UrlEncode(페이로드),
secret
)
🔑 JWT의 동작
- 클라이언트가 로그인을 요청합니다.
- 유효한 로그인 정보라면 서버는 Authorization 헤더에 JWT 토큰을 실어 보냅니다.
- 사용자는 이 토큰을 보관하고 있다가 API 요청을 할 때 토큰과 함께 보냅니다.
- 서버는 전달받은 JWT의 서명 부분을 발행했을 때 사용한 비밀키로 다시 해싱하여 비교하고 유효하다면 응답을 보냅니다.
JWT에도 뚜렷하고 치명적인 단점이 있기 때문에,
사용하기 전에 단점을 보완하기 위한 방법을 진지하게 고민해봐야 합니다.
이번 포스트는 여기까지입니다. 끝까지 봐주셔서 감사합니다.
틀린 부분이 있다면 댓글로 지적 부탁드립니다.
'개발지식' 카테고리의 다른 글
[Open License] 소프트웨어 자유와 공유의 기준 (0) | 2024.11.25 |
---|---|
[프로그래밍 이론] 객체 지향 프로그래밍 (0) | 2024.10.25 |
회원 API 설계하기 (0) | 2024.09.06 |
나도 설명하고 싶다! REST API (1) | 2024.08.28 |
웹 이해하기 (0) | 2024.08.20 |