토큰이 만료되었을 때 Vue에서 어떻게 처리해야 할까?

🤯

Jwt로 인증/인가를 처리할 때 정석은 엑세스 토큰과 리프레시 토큰을 둘다 발급받는 것이다.

엑세스 토큰은 유효기간을 짧게, 리프레시 토큰은 길게 설정하고 엑세스 토큰이 만료되면 리프레시 토큰을 통해 새롭게 엑세스 토큰을 발급받는 방식.

 

근데 난 토큰을 그냥 하나만 받았기 때문에 토큰이 만료되면 그냥 사용자를 로그아웃 시켜야 한다.

물론 api에서 로그아웃하는 일이야 어렵지 않다.

애초에 만료된 토큰으로는 인가 필터를 통과할 수 없어 500 에러를 반환하기 때문이다.

 

그런데 토큰이 만료되었을 때, 화면단에서 로그아웃을 시키려면 어떻게 해야 할까?

우선 내 프로젝트에서 고려할 사항은 다음과 같다.

  • api는 토큰을 발급하고 응답 헤더에 보낸다.
  • axios로 api와 통신한 뷰는 헤더에서 얻은 토큰과 로그인 사용자 정보를 전역 상태로 저장한다.
  • api에서 페이지 이동 자체를 제한할 방법은 없다.

 

생각해본 방법은 아래와 같다.

  1. 로그인이 만료된 사용자가 요청을 보냄
  2. BasicAthenticationFilter에서 토큰 만료를 확인하고 관련 에러를 반환한다.
  3. 이 에러를 try-catch문으로 감싼다.
  4. catch문에 들어오면 상태코드로 401을 생성하고 응답 헤더에 토큰을 빈 문자열로 만들어 반환한다.
  5. 뷰에서는 토큰을 확인하고, 상태정보에 빈 문자열로 토큰을 저장함으로써 로그아웃 처리를 할 수 있다.

 

여기서 로그아웃  여부를 사용자에게 알려주려면

  1. axios.intercepters.response.use에서 응답 헤더에 있는 토큰 token+""을 상태에 저장된 토큰 문자열과 비교한다.
  2. 두 문자열이 서로 다르면 로그아웃된 것이다.
  3. 모달로 인증이 만료되어 로그아웃 되었음을 알리고, 로그인 페이지로 이동시킨다.

cf.

당연히 바뀐다.

axios의 intercepter는 스프링에서 요청을 가로채주는 인터셉터와 동일한 역할을 한다.

그 적용 시점은 요청을 보내기 직전과 응답을 받은 직후이며, 요청이 들어올 때마다 매번 작동한다.

따라서 상태 값이 변경되면, 새로운 요청이 들어올 때 변경이 반영될 것이다.