헤더와 쿠키의 JWT 검증 방식 차이

coldrice99·4일 전
0
post-thumbnail

쿠키에서 JWT를 검증할 때 Bearer 처리가 문제되는 이유는 헤더쿠키가 데이터를 다루는 방식이 다르기 때문입니다. 이를 더 구체적으로 설명하겠습니다.


1. 헤더와 쿠키의 차이

헤더:

  • 헤더는 문자열 형태로 데이터를 전송하며, 클라이언트와 서버 간의 데이터 교환을 위해 사용됩니다.
  • 보통 Authorization 헤더에 JWT를 Bearer {토큰} 형태로 추가합니다.
  • 이 경우, Bearer라는 접두사는 인증 방식의 유형을 나타내며, JWT 라이브러리나 유틸리티에서 이를 고려해 처리할 수 있도록 설계됩니다.

쿠키:

  • 쿠키는 클라이언트가 서버로 전송하는 Key-Value 형태의 데이터 저장 방식입니다.
  • 예: Authorization=Bearer eyJhbGciOiJIUzI1NiJ9...
  • 쿠키 값에는 공백과 같은 문자가 포함되면 문제가 발생할 수 있으므로 URL 인코딩이 필요합니다.
  • 서버에서 쿠키 값을 읽어올 때는 해당 값이 인코딩된 상태로 전달되므로, Bearer 접두사도 그대로 인코딩됩니다.

2. 문제 원인

헤더 기반 검증:

  • Authorization 헤더에서 JWT를 가져올 때, 값은 원래 상태(Bearer eyJhb...)로 저장되므로 Bearer 접두사를 단순히 제거하면 됩니다.

쿠키 기반 검증:

  • 쿠키 값은 URL 인코딩이 되어 전달되며, Bearer와 공백(%20)도 인코딩되어 저장됩니다.
    • 예: Bearer eyJhb...Bearer%20eyJhb...
  • 따라서, 쿠키에서 값을 추출한 후 바로 JWT를 검증하려 하면 Bearer 접두사가 그대로 포함되어 있어 검증이 실패하거나, 디코딩 오류가 발생할 수 있습니다.
    • 공백이 %20로 남아 있거나, 인코딩된 Bearer를 처리하지 않으면 JWT의 유효성 검증 과정에서 문제가 생깁니다.

3. 해결 방법

1. Bearer 접두사 처리

  • 쿠키에서 값을 추출한 후, 직접 Bearer 접두사와 공백을 제거해야 합니다.
    public String getTokenFromRequest(HttpServletRequest req) {
        Cookie[] cookies = req.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("Authorization")) {
                    try {
                        String value = URLDecoder.decode(cookie.getValue(), "UTF-8");
                        if (value.startsWith("Bearer ")) {
                            return value.substring(7); // Bearer 제거
                        }
                    } catch (UnsupportedEncodingException e) {
                        return null;
                    }
                }
            }
        }
        return null;
    }

2. 쿠키 저장 시 Bearer 제외

  • 쿠키에 JWT를 저장할 때, Bearer 접두사를 포함하지 않고 순수한 토큰 값만 저장하는 방법도 있습니다.
  • 이 경우, 검증 시 추가적인 substring 처리가 필요 없으므로 코드가 단순해집니다.
    public void addJwtToCookie(String token, HttpServletResponse res) {
        try {
            String encodedToken = URLEncoder.encode(token, "UTF-8");
            Cookie cookie = new Cookie("Authorization", encodedToken);
            cookie.setPath("/");
            res.addCookie(cookie);
        } catch (UnsupportedEncodingException e) {
            log.error(e.getMessage());
        }
    }

4. 결론

  • 헤더: Bearer {토큰} 구조를 유지하며, 인증 방식 정보(Bearer)와 토큰 값을 동시에 제공.
  • 쿠키: 토큰 값만 저장하거나, 저장된 값을 명시적으로 파싱해 Bearer 접두사를 제거해야 함.

이 차이는 JWT를 사용하는 목적데이터 전달 방식의 차이에서 비롯됩니다. 쿠키를 사용할 때는 이러한 추가 처리가 필요하므로 코드 작성 시 유의해야 합니다.

profile
서두르지 않으나 쉬지 않고

0개의 댓글