JWT란 무엇인가? (개념편)

심주흔·2023년 9월 12일
0
post-thumbnail

토큰 기반 인증과 JWT, 리프레시 토큰의 개념을 이해하고 토큰 기반 인증인 JWT 토큰 서비스를 구현하고 적용하기

🎲 토큰 기반 인증

말 그래도 토큰을 사용하여 사용자를 인증하는 방법

🎯 토큰?

서버에서 클라이언트를 구분하기 위한 유일한 값
서버가 토큰을 생성해서 클라이언트에게 제공하면, 클라이언트는 이 토큰을 갖고 있다가 여러 요청을 이 토큰과 함께 신청 > 서버는 토큰만 보고 유효한 사용자 인지 검증

🎳 <과정>

  1. 클라이언트가 아이디와 비밀번호를 서버에게 전달하면서 인증 요청
  2. 서버는 아이디와 비밀번호를 확인해 유효한 사용자인지 검증
  3. 클라이언트는 서버에서 준 토큰 저장
  4. 이후 인증이 필요한 API를 사용할 때 토큰을 함께 전송
  5. 그러면 서버는 토큰이 유효한지 검증
  6. 토큰이 유효하다면 클라이언트가 요청한 내용 처리

🎳 <특징>

1.무상태성
토큰 기반 인증에서는 클라이언트에서 인증 정보가 담긴 토큰을 생성하고 인증하기 때문에 서버에 데이터를 저장할 필요가 없다. 서버 입장에서는 클라이언트의 인증 정보를 저장하거나 유지하지 않아도 되기 때문에 완전한 무상태(stateless)로 효율적인 검증을 할 수 있다.

2.확장성
서버를 확장할 때 상태 관리를 신경 쓸 필요가 없으니 서버 확장에 용이해진다. 또한, 각종 로그인에 필요한 토큰 기반 인증을 사용하는 다른 시스템에 접근해 로그인 방식을 확장하거나 다른 서비스의 권한을 공유할 수 있다.

3.무결성
토큰을 발급한 이후에 토큰 정보를 변경할 수 없다.

🎲 JWT

🎯 JWT의 구조

aaaaa.bbbbb.cccc

a => 헤더
b => 내용
c => 서명

🎳 헤더

: 토큰의 타입과 해싱 알고리즘을 지정하는 정보를 담는다.

{
   "type" : "JWT",
   "alg" : "HS256"
}
이름설명
typ토큰의 타입을 지정한다. JWT라는 문자열이 들어가게 된다.
alg해싱 알고리즘을 지정한다.(HS256)

🎳 내용

: 토큰과 관련된 정보를 담는다. 내용의 한 덩어리를 claim이라고 부르며, 클레임은 키값의 한 쌍으로 이루어져 있음

<claim의 종류>

  • 등록된 클레임(registered claim) : 토큰에 대한 정보를 담는다.
이 름설명
iss토큰 발급자(issuer)
sub토큰 제목(subject)
aud토큰 대상자(audience)
exp토큰의 만료시간. 시간은 NumbericDate 형식으로하며, 항상 현재시간 이후로 설정
nbfNotBefore.NumbericDate 형식으로 날짜를 지정하며, 이 날짜가 지나기 전까지는 토큰이 처리되지 않는다.
iat토큰이 발급된 시간으로 iat은 issued at을 의미한다.
jtiJWT 고유 식별자로서 주로 일회용 토큰에 사용한다.
  • 공개 클레임(public claim) : 공개되어도 상관 없는 클레임. 충돌을 방지할 수 있는 이름을 가지며, URL로 이름을 짓는다.

  • 비공개 클레임(private claim) : 공개되면 안되는 클레임. 클라이언트와 서버 간의 통신에 사용 됨.

{
	"iss": "ajufresh@gmail.com",	//등록된 클레임
    "iat": 1622370878,				//등록된 클레임
    "exp": 1622372678,				//등록된 클레임
    "https://juheun.com/jwt_claims/is_admin" : true, //공개 클레임(URL)
    "email" : "ajufresh@gmail.com",	 //비공개 클레임
    "hello" : "안녕하세요!"			  //비공개 클레임
}

🎳 서명

: 해당 토큰이 조작되었거나 변경되지 않았음을 확인하는 용도로 사용, 헤더의 인코딩값과 내용의 인코딩값을 합친 후에 주어진 비밀키를 사용해 해시값을 생성

🎯 리프레시 토큰

토큰의 유효시간에 따른 단점을 극복하기 위한 것.
리프레시 토큰은 액세스 토큰과 별개의 토큰이다. 사용자를 인증하기 위한 용도가 아닌 액세스 토큰이 만료 되었을 대 새로운 액세스 토큰을 발급하기 위해 사용한다.
액세스 토큰의 유효 기간은 짧게 설정하고, 리프레시 토큰의 유효 기간은 길게 설정하면 공격자가 액세스 토큰을 달취해도 몇 분 뒤에는 사용할 수 없는 토큰이 되므로 더 안전하다.

🎲 JWT을 사용할 때 주의할 점

  • JWT의 헤더 alg부분을 "none"으로 설정한다면 보안성이 낮아진다. (해싱 알고리즘을 사용하지 않는다.)

  • JWT는 디코딩이 매우 쉽다. > 민감한 정보를 기입하지 않는다. 최소한의 정보만을 담을 수 있도록 한다.

  • 개발자가 개발과정에서 시크릿키를 간단하게 설정하거나, 강의나 인터넷에서 참고한다면 노출되기 쉽다 > 키를 길고 복잡하게 설정, 공유 금지 생성용 키, 검증용 키 2개를 사용하여 운용한다.

  • JWT는 무결성의 특징을 가지고 있기 떄문에 변경하거나 수정하기 어렵다. 이에 따른 해결 방법은 JWT를 해킹할 수 없도록 복잡하게 만들거나, JWT 블랙리스트를 이용하여 특정 사용자는 사용할 수 없도록 한다.(세션방식) 또한 리프레시 토큰을 사용하면 된다.

profile
이봐... 해보기는 했어?

0개의 댓글