[유데미x스나이퍼팩토리] 10주 완성 프로젝트 캠프 - JWT

강경서·2023년 8월 6일
0
post-thumbnail

🔒 JWT

JWT(JSON Web Token)는 일반적으로 클라이언트와 서버, 서비스와 서비스 사이 통신 시 권한 인가(Authorization)를 위해 사용하는 토큰입니다. JSON 개체로 안전하게 전송하기 위한 간결하고 독립적인 방법을 사용하고 디지털 서명이 되어 인증에 신뢰할 수 있습니다.


기존의 많은 브라우저들이 Cookie와 Session을 이용해서 인증 체계를 구성했습니다. HTTP프로토콜의 특징인 Connectionless하고 Stateless한 상태 때문에 생기는 문제로 Cookie와 Session을 사용해 왔지만 Cookie는 보안이 떨어지고 Session은 요청을 진행할때 마다 세션 저장소를 통해 인증을 걸쳐야 하므로 DB에 접근하는 과정이 추가로 필요하다는 단점이 있습니다.

  • Cookie: 클라이언트(로컬)에 저장되는 키와 값이 들어있는 작은 데이터 파일입니다. 이러한 Cookie는 클라이언트에 저장되어 필요시 정보를 참조하거나 재사용할 수 있습니다.
  • Session: 일정 기간 동안 같은 사용자(클라이언트)로 부터 들어오는 일련의 요구를 하나의 상태로 보고 그 상태를 일정하게 유지시키는 기술입니다.

JWT의 등장

JWT는 위와 같이 Cookie와 Session을 사용하면서 생기는 문제를 고찰하다 생긴 인증 방식입니다. 인증에 필요한 정보를 Token에 담아 암호화시켜 사용하는 방법입니다. 기본적인 인증을 진행하는 구조는 Cookie와 크게 다르지 않지만 JWT는 서명된 토큰이라는 점이 특징입니다. 공개 키와 개인 키 두가지를 사용하여 토큰에 서명하여 개인 키를 가진 서버만이 토큰을 인증할 수 있습니다.


JWT의 구조

JWT는 Header, Payload 그리고 Signature 3가지의 구성요소가 점(.)으로 구분되어 있습니다.

xxxxx.yyyyy.zzzzz

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

Header에는 보통 토큰의 타입이나 서명 생성에 어떤 알고리즘을 사용되었는지 저장합니다.


Payload

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

Payload에는 보통 Claim이라는 사용자에 대한, 혹은 토큰에 대한 property를 key-value의 형태로 저장합니다. 표준 스펙상 key의 이름은 3글자로 되어있습니다.

  • iss(Lssuer): 토큰 발급자
  • sub(Subject): 토큰 제목 - 토큰에서 사용자에 대한 식별 값
  • aud(Audience): 토큰 대상자
  • epx(Expiration Time) 토큰 만료 시간
  • nbf(Not Before): 토큰 활성 시간
  • iat(Issued At): 토큰 발급 시간
  • jti(JWT Id): JWT 토큰 식별자

위의 key를 서버의 인증 체계에 따라 사용합니다. 꼭 이 7가지를 모두 포함할 필요는 없고 이외에도 자유롭게 key를 설정하여 추가해도 상관없습니다. 다만 Payload에 민감한 정보는 담지 않아야 합니다. Header와 Payload는 특별한 암호없이 디코딩하여 값을 알 수 있기때문입니다.


Signature

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

Signature는 인코딩된 Header, 인코딩된 Payload를 개인 키와 지정된 알고리즘을 통해 암호화 되어있습니다. 즉 서버가 가지고 있는 개인 키로만 암호화를 풀 수 있습니다.


JWT의 단점과 해결책

많은 장점을 가진 것 같은 JWT에도 단점이 존재합니다. 먼저 Cookie와 Session과 달리 base64 인코딩을 통한 데이터를 전달하므로 전달량이 많아 네트워크 전달 시 부하가 생길 수 있고, Payload에는 암호화가 되어있지 않아 민감한 데이터는 전달할 수 없습니다. 무엇보다 토큰이 탈취당하면 만료될 때 까지 대처가 힘듭니다.

특히 토큰이 탈취당하면 만료될 때 까지 대처가 힘들다는 단점이 매우 크리티컬한 위험요소가 되어 토큰의 만려시간을 짥게 가져가는 방법으로 보안성을 강화합니다. 다만 이렇게 토큰의 만료시간이 짧으면 사용자 입장에서 토큰이 만료될 때 마다 재로그인을 해야하는 불편함이 생깁니다.

짧은 토큰의 만료시간으로 생긴 불편함을 보완하기 위해 Refresh Token을 이용합니다. 토큰을 처음 생성할때 Access Token과 Refresh Token 두가지를 발급하고 만료 시간이 짧은
Access Token을 이용하여 인증을 이용하고 해당 토큰이 만료되면 만료 시간이 비교적 긴 Refresh Token을 이용하여 Access Token을 새로 발급하는 방법으로 불편함을 보완합니다.


JWT를 이용한 API 요청

fetch(url, {
	method: "GET",
    headers: {
    	Accept: "application/json",
        Authorization: token,
    },
}).then((res) => res.json()),

HTTP요청의 Headers값의 Authorization 필드에 JWT 담아 API에 요청을 합니다.


📝 후기

JWT를 이번 팀 프로젝트에서 처음 경험해 보았습니다. 기존의 쿠키와 세션 방법으로 인증 방식을 구현하는 방법이 익숙하여 처음 JWT를 접했을때는 다소 어려움이 있었지만 쿠키와 세션의 단점을 해결할 수 있는 점에 큰 매력을 느꼈습니다. JWT 또한 단점이 존재하는 인증 방식이지만 웹 서비스의 상황가 서버의 상황에 맞게 사용할 수 있는 인증 방식을 또 하나 배운점이 가장 마음에 들었습니다.


🧾 Reference



본 후기는 유데미-스나이퍼팩토리 10주 완성 프로젝트캠프 학습 일지 후기로 작성 되었습니다.

#프로젝트캠프 #프로젝트캠프후기 #유데미 #스나이퍼팩토리 #웅진씽크빅 #인사이드아웃 #IT개발캠프 #개발자부트캠프 #리액트 #react #부트캠프 #리액트캠프

profile
기록하고 배우고 시도하고

0개의 댓글