JWT 토큰
전 게시글에서 여러 가지 로그인 방식 설명에 있어 주로 사용되는 3가지 방법이 있다고 말했다
- 세션 - 쿠키
- 토큰 (jwt 토큰) 방식
- 다른 채널을 통해 인증 (OAuth)
이번 본문에서는 2번을 토큰 방식에 대해 알아볼 것이다.
(본문 길이상 간단하게 설명합니다.)
JWT(JSON WEB TOKEN)은 무엇일까?
먼저 JWT 가 뭔지부터 알고 넘어가자
JWT 토큰은 간단하게 사용자의 정보를 JSON 객체로 안전하게 전 송하기 위한 방법이다.
JWT의 구조
JWT 구조(이미지 출처)
- Header
- 토큰의 유형 , 사용 중인 서명 알고리즘 두 부분으로 구성된다.
-
{ "alg": "HS256", // 서명 알고리즘 "typ": "JWT" // 토큰 유형 }
- Payload
- 등록된 클레임
서비스에 필요한 정보가 아닌 토큰에 대한 정보를 나타내기 위한 클레임 (정의된 클레임 종류) - 공개 클레임
공개용 정보를 전달하기위해 사용됨 - 비공개 클레임
클라이언트 <-> 서버가 정보를 공유하기 위한 사용자 지정 클레임 -
{ "exp": 1622920907, // 등록된 클레임 "iat": 1620328907, // 등록된 클레임 "jti": "a4cd64c8-4abf-49e8-9662-3c2ac1331c2a", // 등록된 클레임 "id": "kjj924", // 비공개 클레임 "email": "kjj924@naver.com" // 비공개 클레임 }
- 등록된 클레임
- Signature
- 해당 토큰이 조작,변경 되지 않았음을 확인하는 데 사용한다.
- 생성 방법은 인코딩(header) , 인코딩(payload) , 비밀 키 를 가지고 header에 지정된 알고리즘을 이용하여 만든다.
-
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
(보안 방법 및 구체적인 내용은 공식 사이트를 참고해주시길 바랍니다)
JWT 토큰을 이용한 인증 흐름
- 클라이언트가 로그인을 서버에 요청합니다.
- 서버는 요청에대한 ID/ PW을 검증하여 맞다면 토큰을 생성합니다.
- 클라이언트에게 토큰을 전달하여 저장시킵니다.
-> (생각해봐야 할 문제 토큰을 어디에 저장할 것인가?)
- 쿠키
- 세션 스토리지
- 로컬 스토리지
- 클라이언트는 요청을 보낼때 Header 영역에 토큰을 포함하여 보냅니다.
-
### 헤더에 Authorization 필드로 토큰을 포함하여 보낸다. GET https:/testpage/members Authorization: Bearer {{auth_token}}
- 서버는 해당 토큰을 검증하여 만료되거나 변조 여부를 확인 후 응답을 돌려줍니다.
그럼 JWT 토큰을 이용하면 이점이 무엇인가?
- 세션 - 쿠키 방식와 비교하여 생각해보자. 이제부터 세션 방식이라고 말하겠습니다. 즉 사용자가 로그인에 성공하면 서버에서 사용자 정보를 세션 저장소에 저장 후 고유한 세션 ID(JSESSIONID) 를 발급하여 사용자 쿠키에 저장시킵니다.
- 사용자는 로그인 후 서버에 요청에 세션 ID를 포함하여 서버에 보내면 서버는 요청에 포함된 세션 ID 를 세션 저장소와 확인하여 사용자를 확인하게 됩니다.
- 세션 방식은 인증정보를 서버에서 관리합니다.
간단하게 정리하자면 사용자 정보를 서버에서 관리하게 된다는 뜻이다.
여기에는 장점도 있지만 단점도 같이 존재하는데 단점 하나만 알아보자.
확장(Scale Out)에 취약하다
서비스가 커지고 사용자가 많아지면 우리는 로드밸런서를 통해 서버를 확장시키고 관리를 진행할 것이다.
아까 언급한 세션방식의 특징 사용자 정보를 서버에서 관리하게 된다
을 상기하고 해당 그림을 보게 된다면
요청마다 클라이언트가 배정되는 서버가 다를 수 있기 때문에 나는 로그인을 했지만 서버가 관리하고 있는 세션 스토어에 존재하지 않을 수 있다. (A서버에 인증을 했지만 B서버에 배정되는 경우)
이러한 문제점을 해결하기 위해 Sticky Session이나 Session Clustering 방식을 사용 한다고 합니다.
하지만 동시에 관리할 Point 도 같이 증가하게 됩니다.(관리할 Point 들이 늘어난다는 뜻은 버그가 발생하기 쉬운 환경이라고 생각합니다)
그럼 JWT 토큰은 확장(Scale Out) 괜찮은가?
JWT 토큰 같은 경우 여러개의 서버가 존재해도 사용자 정보를 서버에서 관리하지 않기 때문에
서버가 동일한 Secret key 만 가지고 있다면 서버로 넘어온 JWT 토큰을 검증하여 사용할 수 있다.
JWT 토큰을 이용하면 발생하는 단점은?
해당 질문은 세션방식이 가지고 있는 장점에 거의 반대되는 성향을 가지고 있는 것 같다.
- JWT 토큰이 탈취당하면 서버에서 해당 토큰을 무력화하기가 어렵다.
(따라서 토큰의 만료기간을 짧게 가져가야 한다.) - JWT 토큰 자체(payload)에 사용자 정보가 있기 때문에 탈취 당하면 정보 노출이 발생할 수 있다.
(따라서 토큰 자체에 중요한 개인정보를 넣지 않도록 해야합니다) - 다중 로그인을 막기 위해 결국 세션이나 다른 방법 혼합하여 사용하게 된다.
'Spring > security' 카테고리의 다른 글
SpringSecurity Test 코드 작성하기 (2) | 2021.05.26 |
---|---|
Spring security 동작 원리 (인증,인가) (3) | 2021.05.04 |