특성
- 유저를 인증하고 식별하기 위한 Claim 기반 Web 토큰
- 세션과 달리 서버가 아닌 클라이언트에 저장 -> 서버 부담 감소
- 토큰 자체에 사용자의 권한 정보나 서비스를 사용하기 위한 정보가 포함됨
- JWT 사용 시 RESTful과 같은 Stateless 환경에서 사용자 데이터를 주고 받을 수 있음
구조
Header, Payload, Signature 각각의 구성요소가 점(.)으로 구분되어 있음
Header
- JWT에서 사용할 타입과 해시 알고리즘의 종료가 담겨있음
Payload
- 서버에서 첨부한 사용자 권한 정보와 데이터가 담겨있음
Signature
- Header, Payload를 Base64 URL-safe Encode 한 이후 Header에 명시된 해시함수를 적용하고, 개인키(Private Key)로 서명한 전자서명이 담겨있음
인증
- 사용자가 ID, PW를 입력하여 서버에 로그인 인증 요청
- 서버에서 클라이언트로부터 인증 요청을 받으면 Header, Payload, Signature 정의하고 각각 Base64로 한 번 더 암호화하여 JWT 생성하고 쿠키에 담아 클라이언트에게 발급
- 클라이언트는 서버로부터 받은 JWT를 로컬 스토리지에 저장(쿠키나 다른 곳에 저장할 수도 있음)하고, API를 서버에 요청할 때 Authorization header에 Access Token을 담아 보냄
- 서버가 할 일은 클라이언트가 Header에 담아서 보낸 JWT가 내 서버에서 발행한 토큰인지 일치 여부를 확인하여 일치하면 인증을 통과시켜주고 아니라면 통과시키지 않음, 인증이 통과되면 페이로드에 들어있는 유저 정보를 select해서 클라이언트에게 돌려줌
- 클라이언트가 서버에게 요청했는데, 액세스 토큰의 시간이 만료되면 클라이언트는 리프레시 토큰을 이용해 서버로부터 새로운 엑세스 토큰 발급받음
장점
- Header와 Payload를 가지고 Signature를 생성하므로 데이터의 위변조를 막을 수 있음
- 인증 정보에 대한 별도의 저장소 불필요
- 토큰에 대한 기본 정보와 전달할 정보 및 토큰이 검증되었음을 증명하는 서명 등 필요한 모든 정보를 자체적으로 지님
- 클라이언트 인증 정보를 저장하는 세션과 달리 서버는 Stateless가 됨
- 서버 확장성 우수
- 토큰 기반으로 다른 로그인 시스템에 접근 및 권한 공유 가능(쿠키와 차이)
- 모바일 환경에서도 동작(세션은 불가능)
단점
- 쿠키/세션과 다르게 토큰의 길이가 길어, 인증 요청이 많아질수록 네트워크 부하 심화
- Payload 자체는 암호화되지 않아 유저의 중요한 정보를 담을 수 없음
- 클라이언트에 저장되기 때문에 DB에서 사용자 정보를 수정해도 토큰에 직접 적용 불가능
보안 전략
짧은 만료 기한 설정
- 토큰이 탈취되더라도 빠르게 만료되기 때문에 피해 최소화
- 유저가 자주 로그인해야하는 불편함
Sliding Session
- 서비스를 지속적으로 이용하는 클라이언트에게 자동으로 토큰 만료 기한을 늘려주는 방법
- 글 작성 / 결제 등을 시작할 때 새로운 토큰 발급
- 사용자는 로그인을 자주 할 필요가 없어짐
Refresh Token
- 클라이언트가 로그인 요청을 보내면 서버는 Access Token 및 그보다 긴 만료 기간을 가진 Refresh Token 발급
- 클라이언트는 Access Token 만료 시 Refresh Token을 사용해 Access Token의 재발급 요청
- 서버는 DB에 저장된 Refresh Token과 비교 후 유효한 경우 새로운 Access Token 발급, 만료된 경우에는 사용자에게 로그인 요구
- Access Token의 만료기한을 짧게 설정할 수 있으며, 사용자가 자주 로그인할 필요가 없어짐
- 서버가 강제로 Refresh Token 만료시킬 수 있음
[참고자료]
https://hudi.blog/self-made-jwt/
https://tecoble.techcourse.co.kr/post/2021-05-22-cookie-session-jwt/
https://velog.io/@hahan/JWT%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80
https://velog.io/@syoung125/JWT-%ED%86%A0%ED%81%B0%EC%9D%B4%EB%9E%80
https://etloveguitar.tistory.com/101
https://brunch.co.kr/@jinyoungchoi95/1
'CS > WEB' 카테고리의 다른 글
SSO(Single Sign-On)란? (0) | 2022.10.24 |
---|---|
OpenID, OIDC(OpenID Connect)란? (0) | 2022.10.24 |
Authentication(인증) vs Authorization (인가) (0) | 2022.10.24 |
OAuth란? (OAuth2.0) (0) | 2022.10.24 |
쿠키(Cookie), 세션(Session), 토큰(Token) 인증 (0) | 2022.10.17 |