JWT에 대해 알아보자!

Ted Hwang
7 min readApr 10, 2019

--

안녕하세요. 내일연구소의 황현태입니다.

저희는 요즘 신규 프로젝트 “K”를 진행하느라 정신없는 4월을 보내고 있습니다. 🏃‍♀🏃

Session과 Cookie🍪로 인증하던 기존 서비스와 달리, 이번 프로젝트 “K” 에서는 전체 서비스의 인증 체계를 Token🎟 기반으로 구축했습니다.

그 과정에서 정리해본 JSON Web Token(이하 JWT)에 대한 내용과 꿀팁을 여러분께 공유합니다.

참고로 이 글은 아래에 해당하는 분들을 위해서 작성했습니다.

️❗️나는 JWT가 뭔지 모른다
️❗️나는 Session-Cookie 방식으로만 인증을 해 봤다
️❗️️나는 Microservice를 JWT 없이 개발 중이다
️❗나는 JWT를 Local Storage에 저장한다.

🎟 JWT?

JWT는 정보를 JSON 객체 형태로 주고 받기 위해 표준규약에 따라 생성한 암호화된 문자열(토큰)입니다. Base64 디코딩만 하면 누구나 내용을 확인할 수 있고, 위변조가 불가능하다는 특징이 있습니다.

발음

RFC 7519에 따르면, ”jot(좉-)”으로 발음합니다.
내일연구소에서는 “제이-더블유-티”로 발음합니다. 😀

구조

JWT는 아래와 같이 세 부분으로 나뉘어져 있습니다. (여기서 직접 만들어볼 수도 있습니다!)

1.Header

Header에는 토큰의 유형과 3.Signature를 만드는데 사용된 해싱 알고리즘이 포함됩니다.

2.Payload

토큰을 통해 전달할 내용이 포함됩니다. 하나의 key-value 쌍을 Claim이라고 부르고, Registered, Public, Private의 3가지 유형으로 나뉩니다. 보통 만료일시, 발급일시, 발급자, 권한정보 등이 포함됩니다.

3.Signature

Payload가 위변조되지 않았다는 사실을 증명하는 문자열입니다. Header, Payload, Secret Key를 해싱하여 제작합니다.

자세한 내용은 공식문서(Link1, Link2)를 참고해주세요 😁

인증 방식 비교하기 : 🎟 vs 🍪

확장성(Scalability)을 고려한다면 Token으로 인증!

Token으로 인증하는 방식은 Session-Cookie로 인증하는 방식에 비해 확장에 유리합니다.

두 방식의 차이점을 확장성 측면에서 살펴보겠습니다.

🍪 Session-Cookie 인증

확장성 👎

  • Stateful : 모든 사용자의 인증상태(Session)를 유지하고 있어야 함
  • Traffic 고려 O: 사용자가 많아지면 Session 저장소가 Traffic을 감당해야 함 (조회, 등록)
  • 공유 자원 O : Server 증설시 Session 저장소를 공유해야 함

🎟 Token 인증

확장성 👍

  • Stateless : Session 저장소 처럼 사용자의 인증 상태 데이터를 별도 저장소로 유지할 필요가 없음
  • Traffic 고려 X, 공유 자원 X : 각 Server가 토큰 발급만 잘 해주면 됨

👨‍👩‍👧‍👦 마이크로서비스? 무조건 JWT 쓰세요!

JWT의 핵심

마이크로서비스에서 JWT로 인증하면 불필요한 인증 과정을 줄여줍니다.

자세한 내용은 아래의 두 가지 토큰을 비교하며 살펴보겠습니다.

A. Payload가 없는 Token (Opaque Token) 👎
B. Payload가 있는 Token (JWT) 👍

A. JWT가 아닌 토큰이라면…

아래 그림은 보통 Oauth2.0하면 생각하는 구조입니다.

이 그림에는 함정이 있습니다! 🃏

Resource 서버가 많아지면 Auth 서버가 너무 바빠집니다. 각각의 Resource 서버가 Token의 유효성, 권한 확인을 Auth 서버에 요청하기 때문입니다. (이미 인증했는데…. 낭비…)

바쁜 Auth 서버…!

그래서 Resource 서버가 많은 마이크로서비스에서는 Token만으로 유효성 & 권한 확인이 가능한 JWT가 필요합니다.

B. JWT와 함께라면!

JWT를 사용하면 Auth 서버에 매번 요청할 필요가 없습니다.

JWT에 모든 정보가 포함되어 있기 때문에, 개별 서비스들은 자체적으로 Token의 유효성, 권한 정보를 체크한 후 바로 Resource를 제공합니다.

🍯 꿀팁s

JWT 사용팁 3가지 (in 웹 브라우저)

1. Local Storage에 저장하지 마세요! ❌

정말 위험합니다! 아무리 데이터 암호화를 잘 해도 Token이 털리면 아무 의미가 없습니다.

Local Storage에 저장하면 웹 브라우저에 영구적으로 저장되고, 자바스크립트를 통해 접근 가능하기 때문에 보안(특히 Cross-Site Scripting 공격)에 취약합니다!

최소한 메모리에 저장해두세요. (ex. Vue.js로 SPA를 개발했다면 Vuex 사용)

2. Silent Auth 🤫

JWT와 Session-Cookie를 모두 사용하기!

사용자의 서비스 경험을 방해하지 않고 인증을 다시 하는 방식입니다. 재인증을 위해 다시 로그인 창을 띄우지 않고, Hidden iframe에서 인증 시 필요한 Redirect 처리까지 진행합니다.

추가 팁! Access Token이 만료되어 다시 인증해서 JWT를 발급받아야 할 때는 Cookie에 로그인 Session 정보를 담아두어서 사용해야 합니다.

(보통 SPA에는 Refresh Token을 제공하지 않습니다. Refresh Token이 있으면 Access Token을 영원히 갱신할 수 있기 때문입니다.)

Why?

  • Local Storage에 JWT를 저장하지 않으면 사용자가 브라우저를 껐다 켤 때 마다 로그인을 다시 해야 합니다.
  • 하지만 로그인에 Cookie를 사용하면 사용자를 방해하지 않고도 (UX 중단 없이, 재-로그인 없이) JWT를 재발급받을 수 있습니다.
  • 게다가 Cookie는 자바스크립트에서 접근을 못하도록 보안 설정이 가능합니다. (Link)

3. 로그아웃 🔓

간단합니다! 저장해둔 JWT를 삭제하면 됩니다. 이제 Client가 서버에 로그아웃을 요청할 필요가 없습니다!

+ 서버에서 블랙리스트를 관리하여 JWT를 만료시키는 방법도 있습니다.

I ❤️ JWT

설계 의도(Why)를 이해하자!

저는 처음에 JWT의 설계 의도를 완전히 이해하지 않은 상태에서 인증 체계를 설계하다 많은 시행착오를 겪었습니다.

설계 의도(Why)를 이해해야 장점을 최대한 활용할 수 있지만, 급하게 진행하다보면 신경을 덜 쓰게 되죠. 😂 다른 분들이 저와 같은 실수를 하지 않으면 좋겠다고 생각해서 이 글을 작성했습니다.

여러분들께서 JWT를 이해하는데 조금이나마 도움이 되었으면 좋겠습니다!

--

--