[Spring boot] [JWT] Spring security와 Redis를 기반으로 한 인증 구현(4) - JWT의 인증과정

김영후·2023년 5월 24일
0

SpringBoot-JWT Auth

목록 보기
4/4

토큰 전달 방식의 변경

이번 글을 작성하기 전, 토큰의 전달 방식을 쿠키에서 헤더로 변경한 것에 대해서 먼저 얘기를 해보고자 한다. 앱개발자 분들과 얘기를 해보니 쿠키보다는 헤더를 이용한 통신에 더 경험이 많았기도 했고, 어차피 토큰 유효성 검증을 서버에서 거친다면 자동으로 없어지지 않는 헤더를 이용해도 상관이 없을 것 같았다. 오히려 유효기간이 되면 자동으로 사라지는 쿠키에 대한 핸들링이 조금 더 복잡성을 높이는 것 같아 토큰 전달 방식을 쿠키에서 헤더로 변경했다. 그럼 본문으로 들어가보도록 하겠다.

JWT를 이용한 인증과 재발급

이전 글에서는 JWT, Redis를 이용한 회원가입 기능 구현에 대해서 알아보았다. 이번 글에서는 회원가입 시 생성한 JWT를 이용한 인증 과정에 대해서 알아보고자 한다.
현재 우리 서비스의 서버단에는 유저 인증, 즉 회원가입, 로그인(리프레시 토큰을 이용한 액세스 토큰 재발급 및 그를 이용한 로그인 / 모든 토큰 만료 시 소셜로그인을 통한 액세스, 리프레시 토큰 재발급), 로그아웃, 회원탈퇴 기능이 구현되어있다. 이 중 JWT를 이용하는 경우는 로그인(리프레시 토큰을 이용한 액세스 토큰 재발급 및 그를 이용한 로그인), 로그아웃, 회원탈퇴가 있다. 이들은 먼저 액세스 토큰을 이용한 인증을 거친 후, 액세스토큰의 만료 여부에 따라 분기처리된다. 예를 들어 로그아웃과 회원탈퇴 시 액세스토큰이 만료되지 않았다면 바로 처리가 될 것이고, 액세스토큰이 만료되었다면 리프레시가 필요하다는 메세지를 리턴해주어 로그인(리프레시 토큰을 이용한 액세스 토큰 재발급 및 그를 이용한 로그인)을 진행 후 재발급받은 액세스 토큰을 이용하여 처리를 하는 것이다. 그럼 먼저 로그인(리프레시 토큰을 이용한 액세스 토큰 재발급 및 그를 이용한 로그인, 이하 액세스 토큰 리프레시)에 대해서 알아보도록 하자.

액세스 토큰 리프레시

액세스 토큰 리프레시는 액세스 토큰이 만료된 상황을 가정한다. 액세스 토큰의 리프레시에는 리프레시 토큰이 이용된다. 그 과정을 도식화하면 아래 그림과 같다.

먼저 과정에서 클라이언트는 서버에 리프레시 토큰과 함께 액세스 토큰 재발급을 요청한다. 이후 서버는 redis에 해당 리프레시 토큰이 저장되어있는지 조회한다. 조회되지 않는 경우 서버에서는 클라이언트에게 재로그인하라는 결과를 리턴해준다. 그럼 클라이언트에서는 소셜플랫폼을 이용한 재로그인을 거쳐 액세스, 리프레시 토큰을 모두 재발급 받아 이후의 요청에 사용하게 되는 것이다. 리프레시 토큰이 redis에서 조회된다면 리프레시 토큰이 아직 유효한 경우이므로 서버는 액세스 토큰을 재생성, 클라이언트에게 발급해주면 된다. 클라이언트는 재발급받은 액세스 토큰을 이후의 요청에 이용하는 것이다.
앞에서 말했던 로그아웃, 회원탈퇴 외에도 액세스 토큰이 필요한 모든 요청에 대해 액세스 토큰의 유효성 검사가 이루어질 것이고, 유효하지 않은 액세스 토큰에 대해 이 과정을 거쳐 액세스 토큰을 재발급 받는다.

로그아웃, 회원탈퇴에서의 액세스토큰 인증

로그아웃과 회원탈퇴에는 액세스 토큰이 필요하다. 이 역시 액세스토큰이 만료되어있다면 리프레시 토큰을 통한 액세스 토큰 재발급 혹은 재로그인이 필요하다. 둘 중 무슨 상황이 되었든, 서버에서는 유효한 액세스 토큰만을 허락하게 했다. 앞의 두 과정 중 아무 상황이든 거친 후에 재발급 받은 액세스 토큰을 이용해 로그아웃과 회원탈퇴를 진행하는데, 사용되었던 액세스 토큰을 블랙리스트 처리하여 혹시나 이후의 요청에 해당 토큰을 이용한다면 해당 요청이 처리가 되지 않게 해주어야한다. 이 블랙리스트에도 redis가 사용된다.
이들의 과정을 도식화하여 보여주겠다. 먼저 로그아웃이다.

2번 과정에서 보이듯 redis에 액세스 토큰을 access token(key):"sign-out"(value) 형식으로 저장한다. 이후 이 액세스 토큰을 이용한 요청이 들어온다면 redis에 저장이 되있는 상태이므로, filter에서 이를 먼저 검증(redis에 저장된 액세스 토큰인지)하면 로그아웃된 유저인지의 여부를 알 수 있다. 회원탈퇴의 경우도 같은 맥락이다.

로그아웃과 회원탈퇴 각각 redis에 저장될 때 value는 다르지만, filter에서 요청에 사용된 액세스 토큰이 redis에 저장되어 있는지 아닌지만 검증한다면 로그아웃하거나 회원탈퇴를 한, 즉 요청 권한이 없는 액세스 토큰임을 알 수 있다.

정리

이번에는 앞서 알아보았던 JWT를 이용하는 방식에 대해 알아보았다. 코드 레벨에서는 알아보지 않았지만, 흐름에 대한 이해를 위주로 작성해보았는데, 잘 이해가 되지 않는 분들이 있을 수도 있겠다는 생각이 든다. 다음 글 부터는 로그인, 로그아웃, 회원탈퇴의 순으로 코드레벨까지 알아보는 글을 작성해보도록 할 것이다.

profile
PNU CSE 16th / Busan, South Korea

0개의 댓글