액세스 토큰 검증 실패(a.k.a 삽질)

N’oublie pas de t’aimer·2025년 3월 13일

DIVE

목록 보기
2/10

로그인 및 회원가입, 네이버 로그인을 시도했다.

로그인이 되지 않는다.

에러메시지를 확인해보자.

jakarta.servlet.ServletException: AccessToken is not valid.
at com.site.xidong.security.JwtAuthenticationFilter.doFilterInternal(JwtAuthenticationFilter.java:50) ~[!/:0.0.1-SNAPSHOT]

JwtAuthenticationFilter 클래스의 50번째 줄에서 액세스 토큰이 유효하지 않은 에러가 발생했다.

JwtAuthenticationFilter를 보자.

@RequiredArgsConstructor
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    private final JwtTokenProvider jwtTokenProvider;

    @Override
    protected void doFilterInternal(HttpServletRequest servletRequest, HttpServletResponse servletResponse, FilterChain filterChain) throws ServletException, IOException {
        String requestURI = servletRequest.getRequestURI();

        List<String> permitAllUrls = Arrays.asList("/siteUser/signup", "/siteUser/login", "/auth/login/kakao/**","/login/oauth2/code/**", "**/error**", "**/oauth2/**", "/api/**", "/auth/*/callback");
        List<String> authUrls = Arrays.asList("/questionSet/create", "/siteUser/myInfo", "/auth/refresh", "/video/**", "/auth/logout", "/comment/**");

        boolean isPermitAll = permitAllUrls.stream().anyMatch(pattern ->
                new AntPathMatcher().match(pattern, requestURI));
        boolean isAuth = authUrls.stream().anyMatch(pattern ->
                new AntPathMatcher().match(pattern, requestURI));
        if (isPermitAll) {
        filterChain.doFilter(servletRequest, servletResponse);
        return;
    } 
    
    if (isAuth) {
        String token = jwtTokenProvider.resolveToken(servletRequest);
        if (token != null && jwtTokenProvider.validateAccessToken(token)) {
            Authentication authentication = jwtTokenProvider.getAuthentication(token);
            SecurityContextHolder.getContext().setAuthentication(authentication);
        } else {
            servletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "로그인이 필요한 기능입니다.");
            return;
        }
    }

    // 위 조건을 통과한 요청은 그냥 필터 체인을 계속 진행
    filterChain.doFilter(servletRequest, servletResponse);
    
}

인증 요청이 들어온 url이 permitAllUrls 중 하나라면 인증이 필요 없는 URL이므로 필터를 통과시키고 더 이상 검증하지 않는다.

인증이 필요한 url이라면 요청에서 토큰을 분리하여 검증하여Authentication 객체 생성 후 SecurityContextHolder에 저장한다.

인스턴스 재부팅을 하면 서버 IP주소가 바뀌는데 프론트엔드에서 서버 요청 IP 주소를 변경하지 않아서 그런 것 같다.

프론트엔드 팀원에게 변경 요청 후

로그인 성공!

profile
매일 1퍼센트씩 나아지기 ୧(﹒︠ ̫ ̫̊ ̫﹒︡)୨

0개의 댓글