🙈

⃝ 동글동글 ⃝

🪐ᐩ˖ 🍎

Spring/Kakao Social Login

[Spring Boot] JWT에 대하여

JONG_UK 2023. 3. 30. 20:46
728x90
반응형
SMALL

카카오 소셜 로그인을 진행하면서 JWT를 다루게 되었습니다.

 

Spring Security와 함께 JWT를 이용하다 보니 조금 복잡한 면도 있고, JWT 자체가 무엇이며, 왜 사용하는지에 대한 의문이 들었습니다. 그래서 JWT에 대해서 적어보려고 합니다.

 

JWT란?

JWT는 Json Web Token의 약자로, 일반적으로 클라이언트와 서버 사이에 통신할 때 권한 인증을 위해 사용하는 토큰입니다.

JSON 형식의 토큰에 대한 표준 규격이며, 주로 사용자의 인증(authentication) 또는 인가(authorization) 정보를 서버와 클라이언트 간에 안전하게 주고받기 위해서 사용됩니다.

 

JWT 토큰은 웹에서 보통 Authorization HTTP 헤더를 Bearer <토큰>으로 설정하여 클라이언트에서 서버로 전송되며, 서버에서는 토큰에 포함되어 있는 서명(signature) 정보를 통해서 위변조 여부를 빠르게 검증할 수 있게 됩니다

 

또한 Spring Boot에서는 Spring Security와 함께 많이 사용됩니다.

 

Spring Security를 사용하다 보면, 401 에러를 많이 볼 수 있는데, 권한이 없기 때문에 나타나는 에러로, 로그인 한 유저에게 JWT를 이용해 사용자에게 권한이 담긴 토큰을 부여해 준다고 생각하시면 될 것 같습니다.

권한 인증 실패 = 401 에러 발생

 

JWT는 헤더(header), 페이로드(payload), 서명(signature) 세 개의 구성요소로 만들어집니다.

 

 

JWT를 생성할 수 있는 사이트의 예시를 들어 설명하도록 하겠습니다.

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io

1. 헤더(Header)

어떤 알고리즘으로 암호화할 것인지, 무슨 토큰을 사용할 것인지에 대한 정보가 들어있습니다.

"alg" : 암호화 방식에는 여러 가지가 있는데 대중적으로 HS512, HS216을 많이 사용합니다.

"typ" : "JWT" JWT 방식을 사용한다는 뜻입니다.

 

2. 페이로드(Payload)

전달하려는 정보가 들어있습니다. 아래의 내용들이 전달하려는 정보가 되며, Clame(클레임)이라고 합니다.

"sub": "1234567890",
"name": "John Doe",
"admin": true,
"iat": 1516239022

페이로드에 들어있는 내용은 수정도 가능하며, 더 많은 정보를 추가할 수 있습니다.

하지만 JWT는 '나는 사용자다'라는 인증에 필요한 최소한의 정보만 담으면 되기 때문에 모든 정보를 담지 말아야 합니다. JWT 토큰은 탈취가 쉽기 때문에 정보의 노출이 쉽게 될 수 있습니다.

password, 개인정보(주민등록번호, 핸드폰번호 등) 같은 데이터는 최대한 담지 않도록 합시다!

 

3. 서명(signature)

보안에 관련된 부분입니다!

헤더와 페이로드에 해당하는 정보를 "개인적으로 지정한" Secret Key로 암호화시켜 토큰을 Decode 하기 어렵게 만듭니다.

따라서 Secret Key를 해커에게 탈취당했다면, 해당 Secret Key로 암호화한 모든 토큰은 복호화할 수 있기 때문에 정보 노출의 가능성이 100%입니다. Secret Key를 절대 GitHub나 다른 사이트에 공유하시면 안 됩니다!

 

JWT를 사용하는 이유와 장점

Session 방식을 사용하지 않아 서버의 부하가 심하지 않습니다. 

일반적인 Session 인증 방식은 클라이언트로부터 요청을 받으면 클라이언트의 상태를 계속해서 유지해 놓고 사용합니다. 이것을 Stateful 특징이라고 하는데, JWT는 Stateless 한 특징을 가지고 있어 상태를 계속 유지해 놓는 것이 아니라, 매 요청마다 토큰을 보내 인증을 받는 방식입니다. 따라서 사용자의 로그인 상태를 계속 유지해 놓지 않기 때문에 인증 정보에 대한 별도의 저장 공간이 필요 없어서 DB와 서버에 부담이 덜해지게 됩니다.

 

확장성이 우수합니다.

 

OAuth의 경우, Facebook, Google, Kakao 등 소셜 계정을 이용하여 다른 웹서비스에서도 로그인할 수 있습니다.

 

모바일 애플리케이션 환경에서도 잘 동작합니다.

 

 

 

JWT의 단점과 주의사항

토큰이 만료되기 전에 노출되면 보안적으로 매우 취약합니다.

 

Clame이 많아질수록 JWT 토큰이 길어져 매 호출 때마다 토큰 데이터를 서버에 전달하는데 JWT 토큰이 길면 네트워크 대역폭 낭비가 심해질 수 있습니다.

 

Payload에 대한 정보는 탈취당할 수 있기 때문에 중요한 데이터(개인정보)를 넣지 않도록 해야 합니다. 

 

JWT는 인증을 위한 토큰입니다. 따라서 Access Token만 있다면 내가 사용자가 아니더라도 인증을 받을 수 있다는 단점이 있습니다.

 

일반적으로 JWT 엑세스 토큰은 인증된 사용자를 대신하여 리소스에 액세스 할 수 있도록 허용하는 권한 부여 토큰입니다. 이 토큰은 일반적으로 사용자의 자격 증명을 인증 서버 또는 ID 공급자와 공유하고 인증 서버 또는 ID 공급자가 발행합니다.

따라서 JWT 엑세스 토큰은 개별 사용자에게 발급되는 것이 아니라 인증 서버 또는 ID 공급자에서 발행되며, 사용자의 자격 증명을 기반으로 구성됩니다. 이 토큰은 사용자가 인증되었음을 증명하며, 사용자가 액세스할 수 있는 리소스와 권한을 지정합니다.

 

다른 사람이 당신의 JWT 엑세스 토큰을 훔쳐서 그 토큰을 사용하여 액세스 허가된 리소스에 접근하려고 시도할 수 있습니다. 이 경우 해당 사용자는 엑세스 토큰에 기록된 사용자로 인증되므로, 해당 사용자가 허용되지 않은 리소스에 액세스하려고 시도하는 경우에도 액세스가 허용될 수 있습니다.

따라서 JWT 엑세스 토큰의 안전한 전송 및 보호가 중요합니다. 이를 위해 HTTPS 프로토콜을 사용하여 인터넷을 통해 전송되는 경우 암호화된 연결을 사용하거나, 토큰을 저장하는 데이터베이스나 쿠키와 같은 저장소를 보호하는 등의 보안 조치를 취할 수 있습니다. 또한 JWT를 사용하는 시스템에서는 토큰의 만료 시간을 적절하게 설정하여 보안성을 높이는 것이 좋습니다.

 

728x90
반응형
LIST