JWT(Json Web Token)은 클라이언트와 서버 간에 안전하게 전송하기 위해 사용되는 방법입니다.
목적은 사용자 인증과 정보 교환 입니다. JWT는 정보가 담긴 JSON 객체를 비밀키로 서명하여 위변조를 방지합니다.
JWT 프로세스
- 로그인 요청 : 사용자가 아이디와 비밀번호 또는 소셜 로그인을 통해 서버에 로그인 요청을 보냅니다.
- 토큰 발급 : 서버는 사용자의 정보로 JWT를 생성합니다. 이때 비밀키로 서명하여 토큰의 진위 여부를 확인할 수 있습니다.
- 토큰 전달 : 서버는 생성한 JWT를 클라이언트에 전달합니다.
- 토큰 저장 : 클라이언트는 전달받은 JWT를 로컬/세션 저장소(local / session Storage) 또는 쿠키에 저장합니다.
- API 요청 시 토큰 포함 : 클라이언트는 이후 API 요청마다 헤더에 JWT를 포함해 서버에 전송합니다.
- 인증 확인 및 응답 : 서버는 전달받은 JWT를 비밀키로 검증하여 사용자가 신뢰할 만한지 확인하고 인증이 성공하면 API 요청에 응답합니다.
※ 왜 매번 토큰을 보내야 하나요 ?
- HTTP는 Connectionlsess 와 Stateless 한 프로토콜이므로 매 요청마다 연결을 새로 맺고 이전 상태를 기억하지 않습니다. 따라서 사용자의 인증 상태를 유지하려면 매번 JWT를 포함해 인증 과정을 거쳐야 합니다.
JWT의 구조
JWT는 Header , Payload , Signature 세 부분으로 구성됩니다.
- Header : JWT의 타입(typ)과 서명 알고리즘(alg)이 들어갑니다. 예로 HS256* 알고리즘은 비밀키 기반의 대칭 암호화 알고리즘 사용 / RS256*은 공개키/개인키 기반의 비대칭 암호화 알고리즘입니다.
- Payload : 인증에 필요한 사용자 정보와 토큰의 유효기간(exp), 발급 시각(iat), 대상(aud)등의 클레임(claim)을 포함합니다.
- Signature : Header와 Payload를 합쳐 비밀키로 암호화한 값입니다. Signature는 토큰의 진위를 확인하는 데 사용됩니다.
JWT의 Header와 Payload는 특별히 암호화된 것이 아니라 Base64 방식으로 단순히 인코딩 되어 있어 누구나 쉽게 내용을 확인할 수 있습니다. 따라서 중요하거나 민감한 정보를 여기에 담으면 안됩니다.
JWT의 진짜 보안은 Signature 에 있습니다. Signature 덕분에 토큰이 위변조되지 않았음을 확인할 수 있기 때문에 인증 과정에서 안전하게 사용할 수 있는 것입니다.
그래서 JWT는 정보를 숨기기보다는 정보가 변경되지 않았다는 것을 보장하는 데 중점을 둔 방식이라고 볼 수 있습니다.
JWT의 장단점
장점
- 서버 상태 유지 불필요 : JWT는 클라이언트에 저장되므로 서버가 별도로 사용자 세션을 저장할 필요가 없습니다.
- 모바일 환경에 적합 : JSON 형식의 토큰은 기기나 플랫폼에 관계없이 사용 가능하여 모바일 앱과 잘 맞습니다.
- 네트워크 부하 감소 : HTTP 헤더 또는 URL 파라미터를 통해 간편하게 전송할 수 있습니다.
단점
- 토큰 크기 관리 필요 : JWT는 일반적으로 세션 쿠키보다 크기 때문에 네트워크 트래픽에 영향을 줄 수 있습니다.
- 만료 후 갱신 어려움 : 토큰이 발급되면 만료 시간 변경이 불가능합니다. 만료된 토큰을 재발급하기 위한 별도의 로직(Refresh Token)이 필요합니다.
JWT의 활용
- API 인증 : 클라이언트가 JWT를 담아 API 요청을 보내면 서버는 토큰을 확인하여 권한이 있는 사용자만 접근을 허용할 수 있습니다.
- 싱글 페이지 애플리케이션(SPA) : 로그인 후 인증 상태를 유지할 때, 클라이언트는 JWT를 저장해 API 요청 시마다 헤더에 포함하여 보낼 수 있습니다.
* HS256 / RS256
HS256과 RS256은 JWT 서명에 사용되는 암호화 알고리즘 입니다. 이는 JWT 보안을 설정할 때 중요한 요소로 선택해야 하는 값 입니다.
HS256 (HMAC SHA-256)
- 대칭 암호화 방식을 사용합니다. 하나의 비밀키를 사용해 토큰에 서명하고 검증할 때도 같은 비밀키를 사용합니다.
- 대칭 암호화는 비밀키 하나만을 사용하기 때문에 구현이 간단하지만, 비밀키를 안전하게 관리해야 합니다. 서버가 비밀키를 관리하며 JWT의 진위 여부를 검증합니다.
- 서버에서 발급한 토큰의 유효성을 다른 서버가 확인할 필요가 없는 환경(단일 서버 환경)에서 주로 사용됩니다.
RS256 (RSA SHA-256)
- 비대칭 암호화 방식을 사용합니다. 개인키로 토큰에 서명하고 공개키로 검증합니다.
- 비대칭 암호화는 서명과 검증에 사용하는 키가 다릅니다. 개인키는 서버에서 안전하게 관리되고 공개키는 누구나 접근할 수 있습니다.
- 주로 다중 서버 환경 또는 외부 서비스와의 통신에서 사용됩니다. 토큰을 발급한 서버와 검증하는 서버가 다른 경우 RS256을 사용해 공개키로 서명을 확인할 수 있습니다.
시스템의 보안 요구 사항에 따라 적합한 알고리즘을 선택해야 한다.
HS256은 단일 서버 환경에서 간단하고 효율적으로 사용할 수 있는 대칭 암호화 방식
RS256은 공개키와 개인키를 사용한 비대칭 암호화 방식으로 다중 서버 또는 외부 서비스 통합시 적합합니다.
'Back-end > Node.js' 카테고리의 다른 글
Node.js 트랜잭션(Transaction) (0) | 2024.09.12 |
---|---|
Node.js 공부시 알아야 할 주요 개념과 기능 (0) | 2024.08.01 |