사용자 인가를 해보자 feat. JWT

0

공통

목록 보기
6/9
post-thumbnail
post-custom-banner

출처 :

⚙️ JWT란?

JWT의 정의

JWT 는 JSON Web Token의 약자로 전자 서명 된 URL-safe (URL로 이용할 수있는 문자 만 구성된)의 JSON입니다.
전자 서명은 JSON 의 변조를 체크 할 수 있게되어 있습니다.
JWT는 속성 정보 (Claim)를 JSON 데이터 구조로 표현한 토큰으로 RFC7519 표준 입니다.
JWT는 서버와 클라이언트 간 정보를 주고 받을 때 Http 리퀘스트 헤더에 JSON 토큰을 넣은 후 서버는 별도의 인증 과정없이 헤더에 포함되어 있는 JWT 정보를 통해 인증합니다.
이때 사용되는 JSON 데이터는 URL-Safe 하도록 URL에 포함할 수 있는 문자만으로 만듭니다.
JWT는 HMAC 알고리즘을 사용하여 비밀키 또는 RSA를 이용한 Public Key/ Private Key 쌍으로 서명할 수 있습니다.

쉽게 설명하자면, JWT (Json Web Token)은 사용자인증을 필요로 하는 통신에서 Request의 헤더에 있는 Token 값으로 유저를 식별하여, 해당 유저의 인증절차를 간소화하는 기법이다. 위와 같은 기법으로 유저 식별이 필요한 기능에 대해 구분할 수도 있고, 쉽게 사용할 수 있다는 장점때문에 많은 언어와 플랫폼에서 사용이 되고 있다.

JWT의 구성

JWT 토큰의 구성의 위와 같이 헤더 . Payload . Signiture로 구분되어 있다. 각 구성의 역할은 다음과 같다.

헤더 (Header)
  • JWT 토큰의 타입과 해시 암호화 알고리즘 정보를 포함하고 있다.
  • 타입 : JWT
  • 알고리즘 : HMAC / SHA256 / RSA
  • 해당 정보가 아래와 같이 인코딩되어 저장되어 있다.

header = {  
	"type": "JWT",
 	"alg": "HS256"
}

# eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
Payload (페이로드)
  • 토큰에 담을 정보를 포함하고 있다. 정보의 한 조각을 클레임이라고 부르고, 한 클레임에 key/value 식으로 데이터가 쌍을 이루어져 있다. 총 3가지 종류의 토큰이 있다.
  1. 등록된 클레임 (registered claim)
  • iss : 토큰 발급자 (issuer)
  • sub : 토큰 제목 (subject)
  • aud : 토큰 대상자 (audience)
  • exp : 토큰 만료시간 (NumericDate 예: 14808421354545)
  • nbf : "Not Before"를 의미하며, 토큰의 활성 날짜와 비슷한 개념이다. 날짜가 지정한 시간보다 지나기전까지 토큰이 처리되지 않습니다.
  • iat : 토큰이 발급된 시간, 이 값을 사용하여 토큰의 age가 얼마나 되었는지 판단할 수 있습니다.
  • jti : JWT의 고유 식별자 / 중복처리를 예방하거나 일회용 토큰을 사용할때 유용하다고 한다.
  1. 공개 클레임 (public 클레임)
  • 이 클레임은 충돌이 방지된 (collision-resistant) 이름을 가지고 있어야 한다고 하고, 충돌을 방지하기 위해서는, 클레임 이름을 URI 형식으로 짓습니다. 사용자가 정의하는 클레임이라고 한다. (한번 써봐야지 알것같다. 뭔지아직 감이 안온다 ㅠㅠ )
 {"https://mangkyu.tistory.com": true } 
  1. 비공개 클레임 (Private Claim)
    비공개 클레임은 사용자 정의 클레임으로, 서버와 클라이언트 사이에 임의로 지정한 정보를 저장한다.
{
    "user_id": "1"
}
서명 (signature)

JSON Web Token의 마지막 부분으로 헤더의 인코딩값과, 정보의 인코딩 값을 합친후 주어진 비밀키로 해쉬를 하여 고유한 암호화 코드이다. BASE64로 인코딩하고, 인코딩한 값을 비밀키(SECRET_KEY)를 이용해 헤더에서 정의한 알고리즘으로 해싱을 하여, 이값을 다시 BASE64로 인코딩한다.

✈️ JWT 동작 방식

일반적인 경우 위와 같은 순서로 진행하게 된다.
1. 클라이언트에서 로그인 요청이 왔을 때 서버에서 secret key를 활용하여 Access Token을 발급한다.
2. 서버에 요청과 권한을 확인하기 위해 헤더에 JWT 전달
3. JWT 서명을 체크하여 사용자 식별 및 권한 확인
4. 클라이언트에 따라 다른 응답 전달.

생성된 토큰은 HTTP 통신을 할 때 Authorization이라는 key의 value로 사용된다. 일반적으로 value에는 Bearer이 앞에 붙여진다.

{ 
 "Authorization": "Bearer {생성된 토큰 값}"
 }

JWT의 단점 😱

  • 토큰 자체에 정보를 담고 있기때문에 보안성이 취약하다.
  • Payload에 3 종류의 클레임을 담고 있기 때문에 정보가 많아질수록 토큰의 길이가 늘어나 네트워크에 부하를 줄 수 있다.
  • Payload는 암호화된 것이 아니라 BASE64로 인코딩 된 정보이기 때문에, 절대 !!!! 중요한 정보를 넣으면 안된다. 왜냐하면, 누구든 토큰의 정보를 갈취하여 BASE64로 디코딩하면 해당 데이터를 확인할 수 있기 때문이다.
  • Stateless : 상태를 저장하기 않기 때문에 한번 만들어지면 제어가 불가능하다. 즉, 토큰을 임의로 삭제하는 것이 불가능하므로 토큰 만료 시간을 꼭 넣어주어서 관리를 해주어야된다.
  • Tore Token : 토큰은 클라이언트 측에서 관리해야하기 때문에 브라우저에 저장될 수 밖에 없다. 그렇기 때문에 항상 해킹의 위험이 생긴다.

끝 🌈

profile
# 개발 # 컴퓨터공학
post-custom-banner

0개의 댓글