JWT란?

이재혁·2024년 5월 14일
0

jwt 인증

  • 용어정리
    • 평문(Plaintext) : 해독 가능한 형태의 메시지(암호화전 메시지)
    • 암호문(Cipertext) : 해독 불가능한 형태의 메시지(암호화된 메시지)
    • 암호화(Encryption) : 평문을 암호문으로 변환하는 과정
    • 복호화(Decryption) : 암호문을 평문으로 변환하는 과정
    • 인코딩(encoding) : 문자를 코드로 변환
    • 디코딩(decoding) : ****코드를 문자로 변환
    • 양방향암호화 : 암호화와 복호화과정을 통해 송.수신간 주고받는 메시지를 안전하게 암.복호화하는 과정
    • 단방향암호화 : 해싱(Hashing)을 이용한 암호화 방식으로 양방향과는 다른 개념으로, 평문을 암호문으로 암호화는 가능하지만 암호문을 평문으로 복호화 하는 것은 불가능.

  • 쿠키 쿠키는 서버가 사용자의 웹 브라우저에 저장하는 데이터를 말합니다. 쿠키의 데이터 형태는 Key 와 Value로 구성되고 String 형태로 이루어져 있습니다.
  • 세션 웹 서버에 웹 컨테이너의 상태를 유지하기 위한 정보를 저장한다. 웹 서버의 저장되는 쿠키(=세션 쿠키)

쿠키와 세션의 차이

  • 쿠키와 세션은 비슷한 역할을 하며, 동작원리도 비슷합니다. 그 이유는 세션도 결국 쿠키를 사용하기 때문입니다.
  • 가장 큰 차이점은 사용자의 정보가 저장되는 위치입니다. 때문에 쿠키는 서버의 자원을 전혀 사용하지 않으며, 세션은 서버의 자원을 사용합니다.

로그인 방식

세션, 쿠키

  • 장점
    • 사용자의 정보는 세션 저장소에 저장되고, 쿠키는 그 저장소를 통과할 수 있는 출입증 역할을 합니다. 따라서 쿠키가 담긴 HTTP 요청이 도중에 노출되더라도 쿠키 자체에는 유의미한 값을 갖고있지 않아서 쿠키에 사용자 정보를 담아 인증을 거치는 것 보다 안전합니다.
    • 각 각의 사용자는 고유의 Session ID를 발급 받기 때문에 일일이 회원 정보를 확인할 필요가 없어 서버 자원에 접근하기 용이합니다.
  • 단점
    • 쿠키에 사용자 정보를 담아 인증을 거치는 것 보다 안전하지만, 해커가 쿠키를 탈취한 후 그 쿠키를 이용해 HTTP 요청을 보내면 서버는 사용자로 오인해 정보를 전달하게 됩니다. 이를 세션 하이재킹 공격이라고 합니다. 해결책으로는 HTTPS 프로토콜 사용과 세션에 만료 시간을 넣어주는 것 입니다.
    • 서버에서 세션 저장소를 사용하기 때문에 추가적인 저장공간을 필요로 합니다.
      • (MySql, Redis, tomcat등)

JWT

  • 장점
    • 간편합니다. 세션과 쿠키를 이용한 인증은 별도의 세션 저장소의 관리가 필요합니다. 그러나 JWT는 발급 후 검증만 거치면 되기 때문에 추가 저장소가 필요없습니다.
    • 확장성이 뛰어납니다. 토큰 기반으로 하는 다른 인증 시스템에 접근이 가능합니다.
  • 단점
    • JWT는 한 번 발급되면 유효기간이 완료될 때까지는 계속 사용이 가능하며 중간에 삭제가 불가능합니다. 따라서 해커에 의해 정보가 털린다면 대처할 방법이 없습니다.
    • Payload 정보가 디코딩하면 누구나 접근할 수 있기에 중요한 정보들을 보관할 수 없습니다.
    • JWT의 길이가 길기 때문에, 인증 요청이 많아지면 서버의 자원낭비가 발생합니다.

Access Token + Refresh Token

  • 설명
    1. 사용자가 ID , PW를 통해 로그인합니다.

    2. 서버에서는 회원 DB에서 값을 비교합니다(보통 PW는 일반적으로 암호화해서 들어갑니다)3~4. 로그인이 완료되면 Access Token, Refresh Token을 발급합니다. 이때 일반적으로 회원DB에 Refresh Token을 저장해둡니다.

    3. 사용자는 Refresh Token은 안전한 저장소에 저장 후, Access Token을 헤더에 실어 요청을 보냅니다.

      6~7. Access Token을 검증하여 이에 맞는 데이터를 보냅니다.

    4. 시간이 지나 Access Token이 만료됐다고 보겠습니다.

    5. 사용자는 이전과 동일하게 Access Token을 헤더에 실어 요청을 보냅니다.

      10~11. 서버는 Access Token이 만료됨을 확인하고 권한없음을 신호로 보냅니다.

      • Access Token 만료가 될 때마다 계속 과정 9~11을 거칠 필요는 없습니다.

      사용자(프론트엔드)에서 Access Token의 Payload를 통해 유효기간을 알 수 있습니다. 따라서 프론트엔드 단에서 API 요청 전에 토큰이 만료됐다면 바로 재발급 요청을 할 수도 있습니다.

    1. 사용자는 Refresh Token과 Access Token을 함께 서버로 보냅니다.

      13. 서버는 받은 Access Token이 조작되지 않았는지 확인한후, Refresh Token과 사용자의 DB에 저장되어 있던 Refresh Token을 비교합니다. Token이 동일하고 유효기간도 지나지 않았다면 새로운 Access Token을 발급해줍니다.

    2. 서버는 새로운 Access Token을 헤더에 실어 다시 API 요청을 진행합니다.

  • 장점
    • Access Token의 유효 기간이 짧기 때문에, 기존의 Access Token만을 이용한 인증보다 안전합니다.
  • 단점
    • 구현이 복잡합니다.
    • Access Token이 만료될 때마다 새롭게 발급하는 과정에서 서버의 자원 낭비가 생깁니다.

JWT

JWT(Json Web Token)란 Json 포맷을 이용하여 사용자에 대한 속성을 저장하는 Claim 기반의 Web Token
JWT는 토큰 자체를 정보로 사용하는 Self-Contained 방식으로 정보를 안전하게 전달한다.
주로 회원 인증이나 정보 전달에 사용되는 JWT는 아래의 로직을 따라서 처리된다.

  • Self_contained 자체적으로 필요한 정보를 담는 방법

클레임(Claim)이란 사용자 정보나 데이터 속성 등을 의미한다.

그래서 클레임 토큰이라 하면 토큰 안에 정보를 담고 있는 토큰이라 생각하면 된다.

예를 들면 아래와 같이 정보를 담고 있는 것을 클레임 기반이라 할 수 있다.

https://jwt.io/

.을 이용한 3개의 구성(Header, Payload, Signature)

Header는 토큰의 타입을 나타내는 typ과 암호화할 방식을 정하는 alg로 구성되어 있습니다.

암호화는 이후에 자세히 설명하겠습니다.

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

Payload

Payload는 토큰에 담을 정보를 포함합니다. 여기서 하나의 정보 조각을 클레임으로 부릅니다. 클레임의 종류로는 Registered, Public, Private로 3가지가 존재합니다. 보통 만료 일시, 발급 일시, 발급자, 권한정보 등을 포함합니다.

{
    "iss": "mju.com",
    "exp": "1485270000000",
    "https://mju.com/jwt_claims/is_admin": true,
    "userId": "11028373727102",
    "username": "mju"
}
  • 등록된 (registered) 클레임,

    등록된 클레임들은 서비스에서 필요한 정보들이 아닌, 토큰에 대한 정보들을 담기위하여 이름이 이미 정해진 클레임들입니다. 등록된 클레임의 사용은 모두 선택적 (optional)이며, 이에 포함된 클레임 이름들은 다음과 같습니다:

    • iss: 토큰 발급자 (issuer)
    • sub: 토큰 제목 (subject)
    • aud: 토큰 대상자 (audience)
    • exp: 토큰의 만료시간 (expiraton), 시간은 NumericDate 형식으로 되어있어야 하며 (예: 1480849147370) 언제나 현재 시간보다 이후로 설정되어있어야합니다.
    • nbf: Not Before 를 의미하며, 토큰의 활성 날짜와 비슷한 개념입니다. 여기에도 NumericDate 형식으로 날짜를 지정하며, 이 날짜가 지나기 전까지는 토큰이 처리되지 않습니다.
    • iat: 토큰이 발급된 시간 (issued at), 이 값을 사용하여 토큰의 age 가 얼마나 되었는지 판단 할 수 있습니다.
    • jti: JWT의 고유 식별자로서, 주로 중복적인 처리를 방지하기 위하여 사용됩니다. 일회용 토큰에 사용하면 유용합니다.
  • 공개 (public) 클레임

    공개 클레임들은 충돌이 방지된 (collision-resistant) 이름을 가지고 있어야 합니다. 충돌을 방지하기 위해서는, 클레임 이름을 URI 형식으로 짓습니다.

    {
        "https://mju.com/jwt_claims/is_admin": true
    }
  • 비공개 (private) 클레임

    등록된 클레임도아니고, 공개된 클레임들도 아닙니다. 양 측간에 (보통 클라이언트 <->서버) 협의하에 사용되는 클레임 이름들입니다. 공개 클레임과는 달리 이름이 중복되어 충돌이 될 수 있으니 사용할때에 유의해야합니다.

    {
        "username": "mju"
    }

Signature

Signature는 Payload가 위변조되지 않았다는 사실을 증명하는 문자열입니다. Base64 방식으로 인코딩한 Header, Payload 그리고 SECRET KEY를 더한 후 서명됩니다.

HMACSHA256 {
  base64UrlEncode(header) + '.' +
  base64UrlEncode(payload),
  your-256-bit-secret
} 

profile
서비스기업 가고 싶은 대학생

0개의 댓글

관련 채용 정보