[Node.js] JWT 로 accesstoken 과 refreshtoken 로 사용자 인증 프로세스 구현

STEVELOPER·2023년 3월 2일
0

Node.js

목록 보기
8/9

플랫폼, 사이트, 모바일 앱등 대부분의 상용화된 애플리케이션들은 회원가입 및 로그인 기능이 구현되어있다.
단순히 이 기능들을 구현하는 것은 간단하지만 보다 보안성이 좋게 만드려면 약간의 기술들이 필요하다.
상대적으로 간단한 기술인 jsonwebtoken 을 구현하는 방법을 정리할 것이다.

서버로는 Node.js express 를 사용하였으며, npm 모듈인 jsonwebtoken 을 사용하였다.

현재 포스트에서 다루는 token 제어는 기술보다 사이클을 이해하는 것이 더 중요한데,
해당 기능을 구현하면서 왜 두가지 token 을 사용하고 어떤 방식으로 동작되는지를 찾아보았다.

accesstoken

accesstoken 이란 말 그대로 접근(access)을 제어하는 token 이다. 즉 이 token 을 통해
사용자 본인이라는 인증이 가능하게 하는 token 인 것이다.
이 token 에는 서버에서 내부적으로 복호화 등을 하여 사용자임을 판별할 수 있는 정보들이 payload(정보) 로 포함된다.

refreshtoken

refreshtoken 은 사용자를 판별할 수 있는 정보를 담고 있지는 않지만 accesstoken 을 재발급 할때 사용하는 token 이다.

기본적인 token process

  1. 우선 사용자는 제일 처음으로 로그인을 할 것이다. 로그인 전에는 accesstoken, refreshtoken 을 가지고 있지 않은 상태이다.

  2. 로그인을 하게되면 첫번째 accesstoken 과 refreshtoken 을 서버로부터 발급받게된다.
    refreshtoken 은 DB 에 저장하고 이후 재발급 및 만료 부분에서 유효성을 검증하는 용도로 사용된다.

  3. 이렇게 사용자(client) 는 특정 저장소, 예를들어 local storage 에 두가지 token 을 가지고 있다가 서버로 요청을 할 때 같이 보내는 것이다.

  4. 요청을 받은 서버는 정보를 반환해주기 전에 우선적으로 accesstoken 을 분석해서 만료된 token 인지, 문제가 있는 token 인지 유효성(availability) 을 판별한다.

  5. 판별후 문제가 없다면 정보를 반환한다.

token 재발급, 만료 process

token 재발급 및 만료를 담당하는 서버 api 를 생성한다.
이 api 는 주기적, 또는 특정 요청을 하기전에 우선적으로 요청하여 token 의 유효성을 판단한다.

  1. accesstoken 과 refreshtoken 을 받아서 우선적으로 refreshtoken 의 유효성을 DB 와 비교하여 판단한다.

  2. refreshtoken 이 문제가 있다면 즉시 만료를 시켜 client 에서 로그아웃 되도록 조치하고, refreshtoken 이 문제가 없다면 이제 만료가 되었는지 확인한다. 이때 경우가 네가지가 존재한다.

  • 두 token 다 만료되지 않음.
  • accesstoken 은 만료되었으나 refreshtoken 은 만료되지 않았음.
  • accesstoken 은 만료되지 않았으나 refreshtoken 은 만료됨.
  • 두 token 다 만료되었음.
  1. 상기 경우는 네가지로 나누어져 있으나 *RTR(Refresh Token Rotation) 이라는 token 구현 방식을 사용하기 위해서 처리는 두가지로 처리할 것이다.
  • 첫번째, 두번째 그리고 세번째의 경우 DB 에 기록돼있는 refreshtoken 과 user 정보를 비교해 유효성을 판단하고 두 token 다 새로 발급하여 반환한다.
  • 네번째의 경우 두 token 다 만료된 상태이므로 client 에서 로그아웃 되도록 조치한다.

*RTR(Refresh Token Rotation) : token 을 사용해서 사용자 인증을 시도하였을 경우 기존 token 은 만료 또는 폐기하고 새로운 token 을 발급하는 방식으로, 보안면에서 좋다.
accesstoken 이나 refreshtoken 이 탈취되었을 경우 만료시간이 되기 전까지는 해커가 정보를 무단으로 사용하게 둘 수 밖에 없으므로 accesstoken 의 시간은 짧게 두는데, 이럴 경우 사용자 입장에서는 빈번한 로그아웃 경험을 하게 될 수 있다.
refreshtoken 을 사용하는 이유는 정상적인 사용자가 잦은 로그아웃 경험을 하게 하지 않으면서 사용자의 정보를 보호하는 것이 주 목적으로, 이렇게 refreshtoken 을 도입하되 RTR 방식 또한 같이 도입하여 주기적으로 token 들을 재발급하면서 보안성도 높이는 것이다.

refreshtoken 의 경우 DB 에 기록돼있으므로 사용자 인증을 시도했을때 문제가 있는 token 이거나 이미 만료된 token 일 경우 만료를 시켜 버리기 때문에 정상적인 사용자와 해커 모두에게서 로그아웃 조치가 되므로 사용자 정보 탈취를 보호할 수 있는것이다.

npm install jsonwebtoken

우선 서버에서 jsonwebtoken 을 install 한다.
token 을 생성하는 방법은 아주 간단하다.

jwt.sign({
  data: 'foobar'
}, 'secret', { expiresIn: '1h' });

상기는 npm 에 등록돼있는 jsonwebtoken 의 메뉴얼에서 가져온 코드인데,
총 인자 세개를 받고있다.
첫번째 데이터(payload), 두번째가 암호키, 세번째는 옵션으로 만료일자등을 지정할 수 있다.
자세한 내용은 참조에 표시된 사이트를 참조하면 된다.
jsonwebtoken 의 경우 base64 로 인코딩 되는것이므로 간단하게 디코딩할 경우
내용을 확인할 수 있어 보안상 중요한 데이터는 포함하지 않는것이 좋다.
혹은 암호화를 시켜서 payload 에 담는 방법도 있다.

REFS

profile
JavaScript, Node.js, Express, React, React Native, GraphQL, Apollo, Prisma, MySQL

0개의 댓글