Spring & SpringBoot

io.jsonwebtoken.MalformedJwtException: Invalid compact JWT string: Compact JWSs must contain exactly 2 period characters, and compact JWEs must contain exactly 4.

땅콩콩 2024. 1. 25. 10:25

Spring security와 jwt를 이용해서 토큰 재발급 api를 구현하고 프론트엔드와 연동해서 테스트하던중 오류가 발생했다.

로그인 과정에서 첫 토큰 세트(accessToken + refreshToken)는 발행이 잘되는데 재발급이 안되는 것이다.

 

일단 내가 생각했던 토큰 발급 로직은 이렇다.

 

- 첫번째 토큰 발급

1. 클라이언트가 아이디, 패스워드를 /login 으로 넘긴다.

2. 내가 사용하는 로그인 필터가 spring security의 UsernamePasswordAuthenticationFilter를 상속하므로 그 정의에 따라서 /login경로로 들어온 요청을 해당 필터에서 검증함.

3. 검증하고 문제가 없으면 accessToken, refreshToken을 발급해서 헤더에 담아 클라이언트에게 넘긴다.
이때 refreshToken을 서버에도 저장해둔다.

 

- 토큰 재발급

1. 클라이언트가 refreshToken을 헤더에 담아 컨트롤러에 별도로 설정해준 재발급 api 엔드포인트로 넘겨준다. 

2. 서버가 토큰을 검증하고 문제가 없으면 새로운 토큰 세트를 발급해서 헤더에 담아 클라이언트에게 넘긴다.

 

근데 토큰을 재발급하는 과정에서 MalformedJwtException 예외가 발생했고,

클라이언트에서 로그를 찍어보니 재발급된 토큰이 들어오지 않고 있었다....

 

<해결!!>

한참 찾았는데 포스트맨으로 확인해보니 토큰 재발급 controller에서 토큰을 http message body에 넘겨주고있었다... 헤더에 담아 넘기는 방식으로 변경했더니 바로 문제가 해결되었다.. ㅡㅡ; 어이없는 실수를 하지않도록 주의하기!!!

 

@PostMapping("/token") //토큰 재발급
    public ResponseEntity token(@RequestHeader("Authorization") String authorization){
        String refreshToken = authorization.split(" ")[1];
        Map<String, String> tokens = memberService.createNewTokens(refreshToken);

        HttpHeaders headers = new HttpHeaders();
        headers.set("accessToken", "Bearer "+tokens.get("accessToken"));
        headers.set("refreshToken", "Bearer "+tokens.get("refreshToken"));

        return new ResponseEntity<>(headers, HttpStatus.OK);
    }