Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JWT Exception Handling #42

Open
ray-yhc opened this issue Aug 11, 2023 · 2 comments
Open

JWT Exception Handling #42

ray-yhc opened this issue Aug 11, 2023 · 2 comments
Labels
🔨 fix 변경 사항 이슈 ❓question 팀원들에게 질문 ♻️ refactor 리팩터링 이슈

Comments

@ray-yhc
Copy link
Contributor

ray-yhc commented Aug 11, 2023

요약

  • Spring Security에서는 JWT에서 발생하는 예외에 대해 다양한 예외 메시지를 제공하고 있습니다.


변조된 토큰을 사용하는 경우.

토큰으로 아무 값이나 사용하는 경우.

토큰이 만료된 경우.

  • 하지만 현 코드에서는 이러한 예외들을 적절히 활용하지 못하고 있는 상황입니다.
  • 따라서 다음과 같이 개선할 것을 제안해봅니다!

AS-IS

  • tokenProvider.getAuthentication(token)에서 토큰 검증을 실행합니다.
  • 검증 과정에서 문제 발생 시, 문제 종류에 관계없이 false가 반환됩니다.
  • Authrization 토큰에 대한 split이 두번 시행됩니다.

@Override
protected void doFilterInternal(HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response, jakarta.servlet.FilterChain filterChain) throws jakarta.servlet.ServletException, IOException {
String token = tokenProvider.resolveToken(request);
if (token != null && tokenProvider.validateToken(token)) {
// check access token
token = token.split(" ")[1].trim();
Authentication auth = tokenProvider.getAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(auth);
}
filterChain.doFilter(request, response);
}

// 토큰 검증
public boolean validateToken(String token) {
try {
// Bearer 검증
if (!token.substring(0, "BEARER ".length()).equalsIgnoreCase("BEARER ")) {
return false;
} else {
token = token.split(" ")[1].trim();
}
Jws<Claims> claims = Jwts.parserBuilder().setSigningKey(secretKey).build().parseClaimsJws(token);
// 만료되었을 시 false
return !claims.getBody().getExpiration().before(new Date());
} catch (Exception e) {
return false;
}
}

TO-BE

  • simpleValidateToken(token)에서는 토큰 문자열 형식에 대해서만 검증을 실행합니다.
  • 토큰 내부에 문제가 있을 시 tokenProvider.getAuthentication(token)에서 종류에 맞는 예외 발생
  • 해당 예외처리는 (1) SecurityConfig 혹은 (2) ApiExceptionHandler @RestControllerAdvice 에서 적절히 처리하여 반환
    @Override
    protected void doFilterInternal(HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response, jakarta.servlet.FilterChain filterChain) throws jakarta.servlet.ServletException, IOException {
        String token = tokenProvider.resolveToken(request);

        //  토큰 문자열 형식에 대해 검증 ("Bearer xxxxx.xxxx.xxx")
        simpleValidateToken(token);
        
        // check access token
        token = token.split(" ")[1].trim();
        Authentication auth = tokenProvider.getAuthentication(token);
        SecurityContextHolder.getContext().setAuthentication(auth);

        filterChain.doFilter(request, response);
    }
    // 41xx : JWT Error
    JWT_SIGNITURE_ERROR(4003, HttpStatus.UNAUTHORIZED, "손상된 JWT 토큰입니다."),
    JWT_MALFORMED_ERROR(4004, HttpStatus.UNAUTHORIZED, "JWT 토큰이 올바르지 않습니다."),
    JWT_EXPIRED_ERROR(4005, HttpStatus.UNAUTHORIZED, "JWT 토큰이 만료되었습니다."),
@ray-yhc ray-yhc added ♻️ refactor 리팩터링 이슈 ❓question 팀원들에게 질문 🔨 fix 변경 사항 이슈 labels Aug 11, 2023
@great-park
Copy link
Member

좋은 것 같습니다! 다만 지금 다른 기능 개발이 우선일 것 같아서, 일단 백로그에 남겨두는건 어떻까요??

@ray-yhc
Copy link
Contributor Author

ray-yhc commented Aug 11, 2023

넵 좋습니다~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔨 fix 변경 사항 이슈 ❓question 팀원들에게 질문 ♻️ refactor 리팩터링 이슈
Projects
None yet
Development

No branches or pull requests

2 participants