인프런 커뮤니티 질문&답변

이재용님의 프로필 이미지

작성한 질문수

코드로 배우는 React with 스프링부트 API서버

Recoil 장바구니 처리

jwt 10분 유효기간 끝나면 apiServer 쪽에서 Expired Exception 발생

24.03.18 12:02 작성

·

318

0

jwt 10분 유효기간 끝난 상황에서

jwtAxios를 이용해서 products 를 호출하면

JWTCheckFilter를 걸쳐서 validateToken 메서드를 호출하고 거기서 Exired Exception 이 납니다.

 

accessToken 이 유효시간(10분)이 경과하였으면

refreshToken 으로 교체되는 걸로 강의내용을 인지했었는데요.

 

제가 어디서 놓친건지 잘 모르겠네요 ㅠ

 

react쪽에서 beforeReq 쪽에서 결국 expired 처리가되고

brforeRes 에서 뭔가 유효기간이 끝났으면

/api/member/refresh 를 호출해야될 것 같은데

 

예제 소스 잘 따라한거

filter에서 먼저 유효기간이 만료되어 exception 부터 호출되어 더이상 진행이 안되네요.

 

어디가 정확히 문제인지 모르겠네요.

jwtUtil.js 는 제공해주신 소스는 오타가 있을까봐

동일하게 ctrl+c , v 도 했습니다.

 

 

JWTUtil.java 일부분

 

public static Map<String, Object> validateToken(String token) {

    Map<String, Object> claim = null;

    try {

        SecretKey key = Keys.hmacShaKeyFor(JWTUtil.key.getBytes("UTF-8"));

        claim = Jwts.parserBuilder()
                .setSigningKey(key)
                .build()
                .parseClaimsJws(token) // 파싱 및 검증, 실패 시 에러
                .getBody();

    } catch (MalformedJwtException malformedJwtException) {
        throw new CustomJWTException("MalFormed");
    } catch (ExpiredJwtException expiredJwtException) {
        throw new CustomJWTException("Expired");
    } catch (InvalidClaimException invalidClaimException) {
        throw new CustomJWTException("Invalid");
    } catch (JwtException jwtException) {
        throw new CustomJWTException("JWTError");
    } catch (Exception e) {
        throw new CustomJWTException("Error");
    }
    return claim;
}

답변 3

0

구멍가게코딩단님의 프로필 이미지
구멍가게코딩단
지식공유자

2024. 03. 18. 17:58

올려두신 코드에서는 JWTCheckFilter에서

만료된 Access Token이 들어오면

response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);

과 같이 예외를 발생하게 됩니다.

 

예제에서는 만료된 Access Token의 경우는 정상적인 응답으로 처리하고 이를 리액트에서 해석한 후에 Refresh Token을 요구하고 있습니다. 이 부분을 401상태로 처리하셔서 Refresh Token을 얻기 위한 호출이 없네요..

 

아래의 코드처럼 정상적인 메세지를 만드시면 자동으로 refresh가 이루어집니다.

 



      Gson gson = new Gson();
      String msg = gson.toJson(Map.of("error", "ERROR_ACCESS_TOKEN"));

      response.setContentType("application/json");
      PrintWriter printWriter = response.getWriter();
      printWriter.println(msg);
      printWriter.close();

 

 

 

이재용님의 프로필 이미지
이재용
질문자

2024. 03. 18. 18:43

response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);

응답코드 때문이였 이였군요!
ㅠㅠ 찾기 어려웠었는데 같이 확인해주셔서 감사합니다!

큰 도움 되었습니다

0

구멍가게코딩단님의 프로필 이미지
구멍가게코딩단
지식공유자

2024. 03. 18. 17:25

build.gradle에서

 

//jwt
implementation 'com.google.code.gson:gson:2.10.1'

implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'

본인 코드에서는 jsonwebtoken의 gson이 추가되어 있네요.. 이거 때문에 날짜 변환시에 double값이 생기면서 문제가 생긴거 같습니다.

 

다른 원인들도 살펴보고 있으니 저녁에 댓글 확인해 주세요^^

0

구멍가게코딩단님의 프로필 이미지
구멍가게코딩단
지식공유자

2024. 03. 18. 14:02

이해하시는 내용이 맞습니다.

Access Token은 만료되면 우선 만료되었다는 메시지가 전송됩니다. -- 1st

이후에 리프레시를 위한 경로를 호출할 때 Access Token과 Refresh Token모두가 필요합니다. -- 2nd

2nd 호출은 리액트 쪽에서 진행되어야 합니다. 이 부분에 문제가 있는 것인지 살펴봐야 하는데..

올려주신 코드만으로는 파악이 좀 어렵네요..

 

깃헙의 경로를 알려주시거나..

 

https://drive.google.com/drive/folders/1ZLHRKaXx8Ou8kZNd1WE6qALxq_wJODXW

에 본인이 작성하신 코드를 올려주시면 살펴볼 수 있습니다.

이재용님의 프로필 이미지
이재용
질문자

2024. 03. 18. 15:47