[Spring] JWT

지인·2023년 6월 24일
0

Spring

목록 보기
4/20

🐰 JWT

JWT (Json Web Token) : 정보가 토큰 자체에 포함된 (Self-Contained) 클레임 (Claim) 기반 토큰

  • 인증(Authentication)권한부여(Authorization)에 사용되는 것이 가장 일반적이다. 인증 절차를 거쳐 서버에서 JWT를 발급해주면, 클라이언트는 이를 잘 보관하고 있다가 API 등을 사용할 때에 서버에 JWT를 함께 제출하며 서버로부터 행위에 대해 인가 받을 수 있다.

  • 해시 혹은 비대칭키 방식을 사용하여 서명(Signature) 하기 때문에 무결성을 검증할 수 있다라는 특징이 있다. 또한 토큰 자신이 정보를 직접 포함하고 있는 특징 덕분에, 통신 양자간 정보를 안전하게 전송할 때에도 사용된다.

🐾 일반적으로 쿠키 저장소를 사용하여 JWT를 저장한다.

🐾 JSOM 객체를 사용하여 정보를 전달

🐾 유저를 인증하고 식별하기 위한 토큰기반 인증


JWT 구조

  • HEADER . PAYLOAD . SIGNATURE
    (헤더 . 내용 . 서명)

    • 헤더, 내용, 서명이 dot을 구분자로 하여 JWT 토큰 1개를 이룬다. 완성된 토큰은 다음의 형태를 가진다.

  • JSON의 경우 개행을 포함할 수 있어, 이를 한줄로 나타내기 위해 최종적으로는 각 구성요소를 Base64로 인코딩한다.

헤더 (Header)

  • typ과 alg 두 가지 정보로 구성된다.

  • typ

    • 토큰의 타입을 지정 ex) JWT
  • alg

    • 알고리즘 방식을 지정하며, 서명 및 토큰 검증에 사용

PayLoad(페이로드)

  • 토큰에서 사용할 정보의 조각들인 클레임이 담겨 있다.

  • 클레임은 총 3가지로 나누어지며, JSON 형태로 다수의 정보를 넣을 수 있다.

1. 등록된 클레임(Registered Claim)

  • 토큰 정보를 표현하기 위해 이미 정해진 종류의 데이터들로, 모두 선택적으로 작성이 가능하며 사용할 것을 권장

  • iss : 토큰 발급자(issuer)

  • sub : 토큰 제목(subject)

  • aud : 토큰 대상자(audience)

  • exp : 토큰 만료 시간(expiration), NumericDate 형식으로 되어 있어야 함 ex) 1480849147370

  • nbf : 토큰 활성 날짜(not before), 이 날이 지나기 전의 토큰은 활성화되지 않음

  • iat : 토큰 발급 시간(issued at), 토큰 발급 이후의 경과 시간을 알 수 있음

  • jti : JWT 토큰 식별자(JWT ID), 중복 방지를 위해 사용하며, 일회용 토큰(Access Token) 등에 사용

2. 공개 클레임(Public Claim)

  • 사용자 정의 클레임으로, 공개용 정보를 위해 사용된다. 충돌 방지를 위해 url 포맷을 이용
{ 
    "https://mangkyu.tistory.com": true
}

3. 비공개 클레임(Private Claim)

  • 사용자 정의 클레임으로, 서버와 클라이언트 사이에 임의로 지정한 정보를 저장
{ 
    "access_token": access 
}

Signature(서명)

  • 토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드

  • 위에서 만든 헤더와 페이로드의 값을 각각 BASE64로 인코딩하고, 인코딩한 값을 비밀 키를 잉요해 헤더에서 정의한 알고리즘으로 해싱을 하고, 이 값을 다시 BASE64로로 인코딩하여 생성한다.

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

JWT 사용 흐름

Client 가 username, password 로 로그인 성공 시

  1. 서버에서 "로그인 정보" -> JWT로 암호화 (Secret Key 사용)

  1. 서버에서 직접 쿠키를 생성해 JWT를 담아 Client 응답에 전달
Cookie cookie = new Cookie(AUTHORIZATION_HEADER, token); // Name-Value
cookie.setPath("/");

// Response 객체에 Cookie 추가
res.addCookie(cookie);
  1. 브라우저 쿠키 저장소에 자동으로 JWT 저장

Client 에서 JWT 통해 인증방법

  1. 서버에서 API 요청 시마다 쿠키에 포함된 JWT를 찾아서 사용

  2. Server

    • 클라이언트가 전달한 JWT 위조 여부 검증 (Secret Key 사용)
    • JWT 유효기간이 지나지 않았는지 검증
    • 검증 성공시,
      • JWT -> 에서 사용자 정보를 가져와 확인

설정하기

  • JWT dependency 추가하기
// JWT
compileOnly group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.5'
runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.5'
runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.5'
  • application.properties
jwt.secret.key=(생성한 secretKey 입력)==

JWT 장/단점

장점

  • 데이터의 위변조를 방지한다.

  • JWT는 인증에 필요한 모든 정보를 담고 있기 때문에 인증을 위한 별도의 저장소가 없어도 된다.

  • 세션(Stateful)과 다르게 서버는 무상태(StateLess)가 된다.

  • 확장성이 우수하다.

  • 토큰 기반으로 다른 로그인 시스템에 접근 및 권한 공유가 가능하다.(쿠키와의 차이)

  • OAuth의 경우 소셜 계정을 통해서 다른 웹서비스에 로그인 할 수 있다.

  • 모바일에서도 잘 동작한다.(세션은 모바일x)

  • 서버에서 가장 피해야 할 것은 DB 조회인데, 서버가 죽는 경우 중 대부분은 DB가 터져서 서버도 같이 죽는 경우이다.
    이와 관련해서 JWT는 DB조회가 필요없다는 장점을 가지고 있다.

단점

  • 쿠키/세션과 다르게 토큰의 길이가 길어, 인증 요청이 많아질수록 네트워크 부하가 심해진다.

  • Payload 자체는 암호화가 되지 않아 중요한 정보는 담을 수 없다.

  • 토큰을 탈취당한다면 대처가 매우 어렵다.


참고

JWT란? 왜 사용할까? 장단점은?
JWT란 무엇인가? 그리고 어떻게 사용하는가? (1) - 개념
직접 만들어보며 이해하는 JWT

profile
열쩡

0개의 댓글