[Spring Security] JWT 기본 개념

·2022년 11월 23일
0

SpringSecurity

목록 보기
9/13
post-thumbnail

JWT(JSON Web Token)

인증에 필요한 정보들을 암호화(인코딩)시킨 JSON 토큰으로 해당 토큰을 HTTP 헤더에 실어 서버가 클라이언트를 식별하는 방식을 JWT 기반 자격 증명 방식이라고 한다.

☝️ 인증에 필요한 정보는 JSON 타입의 데이터! 이것을 Base64 URL-safe Encode를 통해 인코딩하여 직렬화 한 것이 JWT라고 한다. 해당 토큰 내부에는 위변조 방지를 위해 개인키(Secret Key)를 통한 전자서명도 들어있다.

JWT의 종류

JWT도 토큰 탈취의 위험성을 가지고 있기 때문에 사용자의 자격 증명에 Access Token, Refresh Token 두가지 종류의 토큰을 사용한다. 정확하게는 이중으로 나누어 인증을 처리하는 방식을 사용한다고 할 수 있다.

클라이언트가 처음 인증을 받게될 때, 두가지의 토큰을 다 받게된다.

Access Token, Refresh Token는 같은 JWT 토큰이지만 어디에 저장되고, 관리되는냐의 차이를 가진다.

☝️Access Token

클라이언트가 가지고 있는 실질적인 사용자의 자격 증명 정보가 담긴 토큰으로 보호된 정보들에 접근할 수 있는 권한부여에 사용한다.
클라이언트에서 요청이 오면 서버는 해당 토큰에 있는 정보를 활용하여 사용자 정보에 맞게 응답을 진행한다.

✌️Refresh Token

새로운 Access Token발급해주기 위해 사용하는 토큰으로 보통 데이터베이스에 유저 정보와 같이 기록된다.

왜 두가지 토큰을 사용하지🧐

Access Token는 사용자의 자격 증명 정보가 들어가 있기 때문에 해당 토큰이 탈취 당할 가능성이 크다. 그런 문제를 대응하기 위해 Access Token의 유효 기간은 비교적 짧게 설정해 탈취되더라도 오랫동안 사용할 수 없도록 한다.

Access Token의 유효 기간이 끝나면 다시 서버에 인증을 거쳐 Access Token을 받아내야 할까?

NOPE

애초에 서버로부터 가장 처음 JWT 토큰을 받을 때, Access TokenRefresh Token를 같이 보내주는 것은 이러한 점을 고려한 것이다. 사용자는 별도의 재인증을 거치치 않아도 Refresh Token를 통해 Access Token를 재발급 받아 사용할 수 있다.

💡
Access Token : 접근
Refresh Token : 재발급

Refresh Token을 통한 Access Token 재발급 과정

JWT의 구조

JWT는 .을 기준으로 3개의 부분으로 나눌 수 있다.

💡JWT는 Json타입의 토큰이므로 Json포맷으로 정의한다. 각 부분의 Json 포맷은 base64 방식으로 인코딩해 부분을 완성한다.

  • 어떤 종류의 토큰인지, 어떤 알고리즘으로 Sign할지 정의하는 부분.
  • alg : 서명 암호화 알고리즘
  • typ : 토큰 유형

Payload

  • 서버에서 활용할 수 있는 사용자의 정보가 담겨 있다.
  • 사용자 정보나 접근 권한에 대한 내용을 담을 수 있다.
  • 단순 인코딩된 값이 담기기 때문에 민감한 정보는 담지 않도록 주의해야 한다.

🧐 Claim : 토큰에서 Key-Value 형식으로 이루어진 사용할 정보의 조각들을 말한다.

Payload의 Claim은 대표적으로 세가지로 분류할 수 있다.

Registered claims

  • 미리 정의된 클레임
    • iss(issuer, 발행자)
    • exp(expireation time, 만료 시간)
    • sub(subject, 제목)
    • iat(issued At, 발행 시간)
    • jti(JWI ID)

Public claims

  • 사용자가 정의할 수 있는 클레임
  • 공개용 정보 전달을 위해 사용한다.

Private claims

  • 해당하는 당사자들 간에 정보를 공유하지 위해 만들어진 사용자 지정 클레임
  • 공유 받는 특정 유저들을 구분할 수 있는 정보를 담는다.

Signature

  • 원하는 비밀 키(Secret Key)와 Header에서 지정한 알고리즘을 사용하여 Header와 Payload에 대해서 단방향 암호화를 수행한다.
  • 암호화 된 메세지는 토큰의 위변조 유무를 검증하는데 사용한다.

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

💡Header와 Payload는 단순히 인코딩된 값이 때문에 누군가 복호화 및 조작이 가능하다. 하지만 Signature는 서버에서 관리하는 비밀키임으로 유출되지 않는 이상 복호화가 불가능해 토큰의 위변조 여부를 확인하는데 사용하는 것이다.

JWT의 인증 절차

  1. 클라이언트가 서버에 로그인 정보(Username & password)를 담아 요청을 보낸다.

  2. 서버는 로그인 정보가 DB에 저장되어 있는 정보와 일치하는지 검증한 후, 암호화된 토큰(AccessToken, RefreshToken)을 생성한다.

  3. 서버는 암호화된 토큰을 클라이언트에게 보내고, 클라이언트는 토큰을 저장한다.

    • 저장 위치는 Local Storage, Session Storage, Cookie 등이 될 수 있다.
  4. 클라이언트가 HTTP Header 또는 쿠키에 토근을 담아 request를 보낸다.

  5. 서버는 토큰을 해독하고 검증에 통과하면, 클라이언트의 요청에 대한 응답을 보낸다.

JWT의 장단점

장점👍

  1. 상태를 유지하지 않고(Stateless), 확장에 용이한(Scalable) 애플리케이션을 구현하기 용이

  2. 클라이언트가 request를 전송할 때마다 자격 증명 정보를 전송할 필요가 없다.

  3. 인증을 담당하는 시스템을 다른 플랫폼을 분리하는 것이 용이하다.

  4. 권한 부여에 용이하다.

  5. 인증 정보를 저장할 별도의 저장소가 필요하지 않다

단점👎

  1. Payload는 디코딩이 용이해, 민감한 정보를 담았을 경우 탈취 위험성이 있다.

  2. 토큰의 길이가 길어지면 네트워크 부하를 줄 수 있다.

  3. 토큰은 자동으로 삭제되지 않아 반드시 만료 기간을 추가해주어야 한다.

  4. 토큰은 클라이언트 측에서 관리하고 저장하기 때문에 토큰 자체를 탈취당하면 대처하기가 어렵다.

참고 블로그

profile
🧑‍💻백엔드 개발자, 조금씩 꾸준하게

0개의 댓글