문제 상황
access token이 만료될 경우, 토큰을 재발급하기 위해 토큰 만료에 대한 예외처리가 필요했다
처음에는 아무생각 없이 JwtTokenFilter에서 예외를 던지면 Exception Handler에서 처리하지 않을까 했다
그러나 당연히 처리하지 못했고 filter는 dispatcher servlet 보다 앞단에 존재하기 때문에 Exception Handler로는 처리하지 못한다는 것을 알았다.
문제 해결
filter exception handler를 검색하던 중 현재 필터보다 앞단에 예외 처리를 위한 필터를 하나 더 두는 방법을 찾았다
즉, 원래는 요청 -> JwtTokenFilter 의 형태였다면, 요청 -> JwtExceptionFilter -> JwtTokenFilter로 필터를 구성해서 JwtTokenFilter에서 던진 예외를 JwtExceptionFilter가 처리할 수 있도록 했다.
@Component
public class JwtExceptionFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws ServletException, IOException {
try {
chain.doFilter(req, res); // go to 'JwtAuthenticationFilter'
} catch (JwtException ex) {
setErrorResponse(HttpStatus.UNAUTHORIZED, res, ex);
}
}
public void setErrorResponse(HttpStatus status, HttpServletResponse res, Throwable ex) throws IOException {
res.setStatus(status.value());
res.setContentType("application/json; charset=UTF-8");
JwtExceptionResponse jwtExceptionResponse = new JwtExceptionResponse(ex.getMessage(), HttpStatus.UNAUTHORIZED);
res.getWriter().write(jwtExceptionResponse.convertToJson());
}
}
public class JwtTokenFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain)
throws ServletException, IOException {
try {
...
} catch (IllegalArgumentException e) {
logger.error("an error occured during getting username from token", e);
throw new JwtException("유효하지 않은 토큰");
} catch (ExpiredJwtException e) {
logger.warn("the token is expired and not valid anymore", e);
throw new JwtException("토큰 기한 만료");
} catch (NullPointerException e) {
throw new JwtException("토큰 정보 없음");
}
}
}
'TIL' 카테고리의 다른 글
[Sql] 문제 풀이 (0) | 2023.03.04 |
---|---|
[Sql] 문자 함수 (0) | 2023.03.01 |
[Java] stream (0) | 2023.02.15 |
[Java] 두 날짜 차이 계산 (0) | 2023.02.14 |
[Spring] CORS 허용하는 방법 (0) | 2023.02.10 |