1 분 소요

토큰 정보가 null인 경우

문제 상황

로그인을 성공해 얻은 JWT 토큰 정보를 헤더에 넣어서 인증이 필요한 API를 테스트하는 중이었는데 계속 403 에러가 발생했다.
어차피 JWT 필터에서 토큰 정보를 헤더에서 가져와 검증하는 과정을 거치기 때문에 doFilter()에서 로그를 찍어봤는데 토큰이
정상값이 아닌 null이었다😭

다음은 doFilter() 내용이다.
jwtTokenProvider.resolveToken()를 호출해 얻은 token 값이 null이었다..!

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {
    //헤더에서 토큰 가져오기 -> token == null
    String token = jwtTokenProvider.resolveToken((HttpServletRequest) request);

    if (token != null && jwtTokenProvider.validateToken(token)) {
        Authentication authentication = jwtTokenProvider.getAuthentication(token);
        SecurityContextHolder.getContext().setAuthentication(authentication);
    }

    chain.doFilter(request, response);
}

해결

resolveToken()을 확인해보니 request.getHeader() 파라미터가 X-AUTH-TOKEN으로 설정돼 있었고
나는 postman에서 토큰을 Authorization에 넣어주고 있었기 때문에 계속 null을 반환하고 있었던 거였다!
Authorization으로 수정해주니 입력한 토큰값을 정상적으로 가져오기 시작했다.

public class JwtTokenProvider {
  ...
  //request의 header에서 token 얻음
    public String resolveToken(HttpServletRequest request) {
        return request.getHeader("Authorization");
    }
}

Unable to read JSON value

문제 상황

헤더를 통해 토큰이 정상적으로 들어오는 것 까지는 확인을 했으나 테스트헤보니 여전히 403 에러를 뱉어냈다.
로그를 찍어보니 토큰 유효성 검사를 통과하지 못한다는걸 알게됐고, 다음 에러를 뱉고 있었다.

Unable to read JSON value

아래는 에러가 발생했던 함수 validateToken() 내용이다.

public class JwtTokenProvider {
  ...
  //토큰 유효성 검사
  public boolean validateToken(String token) {
      try {
          Jws<Claims> claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token);
          return !claims.getBody().getExpiration().before(new Date());
      } catch (Exception e) {
          log.info("exception: {}", e.getMessage());
          return false;
      }
  }
}

해결

토큰값이 올바르지 않을 때 발생하는 문제다.
나같은 경우 postman에서 API 테스트를 위해 직접 헤더의 AuthorizationBearer {token 값}을 입력해주고 있었는데,
Bearer를 지우고 {token 값}만 입력해주니 200과 함께 원하는 정보를 응답으로 받을 수 있었다!

Reference

참고

세션 설정 해제

JWT를 사용한다면 쿠키로 사용자를 인증한다는 뜻이므로 세션을 사용하지 않기때문에 따로 설정해줘야 한다.
스프링 시큐리티 설정 함수 filterChain()에서 SessionCreationPolicy.STATELESS를 설정해주자.

@Configuration
@EnableWebSecurity
public class SecurityConfig {
  ...
  
  @Bean
  SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

      http
          .csrf(AbstractHttpConfigurer::disable)
          .sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
      ...
  }
}

Reference

카테고리:

업데이트:

댓글남기기