[Web] - JWT


세션과 쿠키를 이해했다는 전제에서 설명하겠다.

로그인


로그인에는 크게 2가지로 나눠진다.

  • Authentication(인증) : 아이디, 패스워드 등으로 유저를 확인한다.
  • Authorization(허가) : 인증된 유저의 권한을 확인 하고 해당 기능을 허가 한다.

기존 방식


기존에는 쿠키와 세션을 활용하여 처리하였다. (아직도 많은 웹이 그렇다.)

모든 기술이 그렇듯 세션과 쿠키의 단점에 의해서 JWT가 탄생하였다. 단점을 알아보자.

  • 메모리 차지
  • 멀티 서버 환경 (MSA 등)에서 골치 아픔

기존 HTTP의 stateless한 상태를 유지하면서 처리 하기 위해 JWT방식이 만들어졌다.

JWT


JWT는 Json Web Token의 약자로 유저 정보를 서버가 아니라 클라이언트가 온전히 다 저장하도록 처리한다. 즉, 서버의 부담이 줄고 stateless한 상태를 유지하도록 해준다.

어떻게 그것이 가능하고 보안문제는 어떻게 처리하는지 알아보자.

  • header : 여기에는 type:”jwt”가 고정으로 들어간다.
  • payload : 해당 부분에 유저 정보와 권한 사항들이 들어간다.
  • verify signature : 이 부분 덕분에 보안 유지가 가능하다.

기본적으로 base64로 encode하기 때문에 jwt.io를 통해 decode해볼 수 있다.


jwt 타입이 고정적으로 들어가고

알고리즘 종류가 들어간다.

PayLoad


여러 권한 정보 및 추가 정보들을 넣는다.

그렇다면 의문이 생길 수 있다.

클라이언트에 보관한다는 권한 정보를 수정해서 서버 요청을 보내면 어떻게 할것인가?

보안에 대한 이슈는 다음 내용에서 설명이된다.

Verify Signature


바로 이 부분 덕분에 jwt가 클라이언트에 온전히 저장하면서 보안을 유지할 수 있다.

Header + PayLoad와 서버에 숨겨져 있는 Secret Key를 통해 암호화 한다.

Secret Key는 서버에만 존재하기 때문에 PayLoad를 수정한 jwt를 보내면 서버측에서는 verify Signature의 값이 동일하지 않음을 보고 invalid token이라고 판단하게 된다.

단점


클라이언트에 저장함으로 모든 문제가 해결되는 것 같지만 jwt 또한 만능이다 아니다.

큰 단점으로는 서버 측에서 통제가 안된다는 문제가 있다.

기존 세션의 경우 다중 접속 방지를 위해서 서버 측에서 세션을 날려서 로그인을 강제로 종료 시킬 수 있었다.

하지만 jwt의 경우 만료시간을 주어도 그 시간 내에서는 자유롭게 드나 들 수 있다는 문제가 있다.

해당 이슈를 다음과 같은 방식으로 처리하기도 한다.

Access_token & Refresh_token


토큰을 2가지 발행해준다.

access_token에 권한 및 여러 정보가 있지만 만료시간을 몇분정도로 짧게 만들어서 발급해준다.

refresh_token은 보통 2주의 긴 만료시간을 가지며 대응하는 값을 서버에 저장한다. (세션처럼 관리하기 위함)

access_token의 만료 시간이 될때마다 refresh_token을 통해 새로운 access_token을 만든다.

만약 서버측에서 유저를 강제로 로그아웃 시키고 싶다면 서버에 저장된 refresh_token을 날리면 access_token은 몇분이라는 짧은 만료시간 이후에 강제 종료되게 된다.

완벽한 해결법은 아니지만 위와 같은 방식으로 많은 로그인 시스템이 개발 되고 있다.