Section 4 JWT(JSON Web Token) (2)

챠오·2023년 1월 18일
0

코드스테이츠

목록 보기
6/7

JWT(JSON Web Token)란?

JWT(JSON Web Token)는 데이터를 안전하고 간결하게 전송하기 위해 고안된 인터넷 표준 인증 방식으로써 토큰 인증 방식에서 가장 범용적으로 사용되며 JSON 포맷의 토큰 정보를 인코딩 후, 인코딩 된 토큰 정보를 Secret Key로 서명(Sign)한 메시지를 Web Token으로써 인증 과정에 사용한다.

JWT의 종류

JWT는 보통 다음과 같이 두 가지 종류의 토큰을 사용자의 자격 증명에 이용한다.

  • 액세스 토큰(Access Token)

  • 리프레시 토큰(Refresh Token)

Access Token은 보호된 정보들(사용자의 이메일, 연락처, 사진 등)에 접근할 수 있는 권한부여에 사용한다.

클라이언트가 처음 인증을 받게 될 때(로그인 시), Access Token과 Refresh Token 두 가지를 다 받지만, 실제로 권한을 얻는 데 사용하는 토큰은 Access Token이다.

"그럼 Access Token 만 있으면 되는 것 아닌가요? 🤔"

맞다. 권한을 부여받는 데엔 Access Token만 가지고 있으면 된다.

하지만 Access Token을 만약 악의적인 사용자가 얻어냈다면 어떻게 될까?
이 악의적인 사용자는 자신이 00사용자인 것 처럼 서버에 여러 가지 요청을 보낼 수 있다.

⭐ 그렇기 때문에 Access Token에는 비교적 짧은 유효 기간 을 주어 탈취되더라도 오랫동안 사용할 수 없도록 하는 것이 좋다.

Access Token의 유효기간이 만료된다면 Refresh Token을 사용하여 새로운 Access Token을 발급받습니다. 이때, 사용자는 다시 로그인 인증을 할 필요가 없다.

"Refresh Token 도 탈취 당한다면요? 🤔"

유효기간이 긴 Refresh Token 마저 악의적인 유저가 얻어낸다면 큰 문제가 될 것이다.

Refresh Token을 이용해 Access Token을 다시 발급받으면 사용자에게 피해를 입힐 수 있기 때문이다.

그렇기 때문에 사용자의 편의보다 정보를 지키는 것이 더 중요한 웹 애플리케이션은 Refresh Token을 사용하지 않는 곳이 많다.

세상에 완벽한 보안은 없으므로 (있다면 쿠키, 세션, JWT, OAuth 등 다양한 방법들을 공부하지 않아도 될 것이다.) 각 방법들의 장단점을 참고하며 필요에 맞게 사용하는 것이 좋다.


JWT 구조

JWT는 위 그림과 같이 . 으로 나누어진 세 부분이 존재한다.

  • Header

Header는 이것이 어떤 종류의 토큰인지(지금의 경우엔 JWT), 어떤 알고리즘으로 Sign할지 정의합니다. JSON Web Token이라는 이름에 걸맞게 JSON 포맷 형태로 정의한다는 것을 기억하자.

{
"alg": "HS256",
  "typ": "JWT"
}

이 JSON 객체를 base64 방식으로 인코딩하면 JWT의 첫 번째 부분이 완성된다.

  • Payload

Payload에는 서버에서 활용할 수 있는 사용자의 정보가 담겨 있다.

어떤 정보에 접근 가능한지에 대한 권한을 담을 수도 있고, 사용자의 이름 등 필요한 데이터를 담을 수 있다.

Payload는 다음으로 설명할 Signature를 통해 유효성이 검증될 정보이긴 하지만, 민감한 정보는 담지 않는 것이 좋다.

{
  "sub": "someInformation",
  "name": "phillip",
  "iat": 151623391
}

첫 번째 부분과 마찬가지로, 위 JSON 객체를 base64로 인코딩하면 JWT의 두 번째 블록이 완성된다.

  • Signature

base64로 인코딩된 첫 번째, 그리고 두 번째 부분이 완성되었다면, Signature에서는 원하는 비밀 키(Secret Key)와 Header에서 지정한 알고리즘을 사용하여 Header와 Payload에 대해서 단방향 암호화를 수행한다.

이렇게 암호화 된 메시지는 토큰의 위변조 유무를 검증하는데 사용된다.

예를 들어, 만약 HMAC SHA256 알고리즘(암호화 방법 중 하나)을 사용한다면 Signature는 아래와 같은 방식으로 생성된다.

HMACSHA256(base64UrlEncode(header) + '.' + 
base64UrlEncode(payload), secret);

JWT 사용 예시

JWT는 권한 부여에 매우 유용하다.

새로 다운받은 A라는 앱이 Gmail과 연동되어 이메일을 읽어와야 한다고 생각해보자.

  1. 이 경우, 사용자는 Gmail 인증서버에 로그인 정보(아이디, 비밀번호)를 제공한다.

  2. 인증에 성공할 경우, JWT를 발급받는다.

  3. A 앱은 JWT를 사용해 해당 사용자의 이메일을 읽거나 사용할 수 있다.


토큰기반 인증 절차

  1. 클라이언트가 서버에 아이디/비밀번호를 담아 로그인 요청을 보낸다.

  2. 아이디/비밀번호가 일치하는지 확인하고, 클라이언트에게 보낼 암호화 된 토큰을 생성한다.

  • Access Token과 Refresh Token을 모두 생성한다.

    • 토큰에 담길 정보(Payload)는 사용자를 식별할 정보, 사용자의 권한 정보 등이 될 수 있다.
    • Refresh Token 이용해 새로운 Access Token을 생성할 것이므로 두 종류의 토큰이 같은 정보를 담을 필요는 없다.
  1. 토큰을 클라이언트에게 전송하면, 클라이언트는 토큰을 저장한다.
  • 저장하는 위치는 Local Storage, Session Storage, Cookie 등이 될 수 있다.
  1. 클라이언트가 HTTP Header(Authorization Header) 또는 쿠키에 토큰을 담아 request를 전송한다.
  • Bearer authentication을 이용한다.
  1. 서버는 토큰을 검증하여 "아 우리가 발급해 준 토큰이 맞네!"라는 판단이 될 경우, 클라이언트의 요청을 처리한 후 응답을 보내준다.


핵심 포인트

  • JWT는 일반적으로 다음과 액세스 토큰(Access Token)과 리프레시 토큰(Refresh Token)을 사용자의 자격 증명에 이용한다.

  • Access Token에는 비교적 짧은 유효 기간 을 주어 탈취 되더라도 오랫 동안 사용할 수 없도록 하는 것이 권장된다.

  • JWT는 Header.Payload.Signature의 구조로 이루어진다.

  • Base64로 인코딩되는 Payload는 손쉽게 디코딩이 가능하므로 민감한 정보는 포함하지 않아야 한다.

profile
무용한 헛소리들

0개의 댓글