군만두의 IT 공부 일지

[1주차] 내일배움캠프 Spring Java 심화 부트캠프 3기 - JWT 본문

개발일지/스파르타코딩클럽

[1주차] 내일배움캠프 Spring Java 심화 부트캠프 3기 - JWT

mandus 2025. 2. 7. 14:53

오늘은 인증과 인가, 쿠키와 세션, JWT에 대해서 공부했다. 각각에 대해서 간단히 정리해보려고 한다. 어려운 부분이니만큼 실습을 따라서 제대로 공부하려고 한다.

1. 인증과 인가

  • 인증(Authentication): 해당 유저가 실제 유저인지 인증하는 개념
  • 인가(Authorization): 해당 유저가 특정 리소스에 접근이 가능한지 허가를 확인하는 개념

웹 애플리케이션 인증

  1. 일반적으로 서버-클라이언트 구조로 되어있다.
  2. Http라는 프로토콜을 이용하여 통신하는데, 그 통신은 비연결성(Connectionless) 무상태(Stateless)로 이루어진다.

웹 애플리케이션 인증 방식

  1. 쿠키-세션 방식의 인증
    • 서버가 '특정 유저가 로그인 되었다'는 상태를 저장하는 방식
    • 서버는 인증과 관련된 최소한의 정보만 저장해서 로그인을 유지시킨다. 
  2. JWT 기반 인증
    • JWT(JSON Web Token): 인증에 필요한 정보들을 암호화시킨 토큰
    • 쿠키/세션 방식과 유사하게 JWT 토큰(Access Token)을 HTTP 헤더에 실어 서버가 클라이언트를 식별한다.

▲ 쿠키-세션 방식과 JWT 기반 인증

2. 쿠키와 세션

  1. 쿠키
    • 클라이언트에 저장될 목적으로 생성한 작은 정보를 담은 파일
    • 구성요소:
      • Name(이름)
      • Value(값)
      • Domain(도메인)
      • Path(경로)
      • Expires(만료기한)
  2. 세션
    • 서버에서 일정시간 동안 클라이언트 상태를 유지하기 위해 사용된다.
    • 서버에서 클라이언트 별로 유일무이한 '세션 ID' 를 부여한 후 클라이언트 별 필요한 정보를 서버에 저장한다.
    • 서버에서 생성한 '세션 ID' 는 클라이언트의 쿠키값('세션 쿠키' 라고 부름)으로 저장되어 클라이언트 식별에 사용된다.
    • 서버는 세션ID 를 사용하여 세션을 유지한다.
      1. 클라이언트가 서버에 1번 요청
      2. 서버가 세션ID 를 생성하고, 쿠키에 담아 응답 헤더에 전달
        • 세션 ID 형태: "SESSIONID = 12A345"
      3. 클라이언트가 쿠키에 세션ID를 저장 ('세션쿠키')
      4. 클라이언트가 서버에 2번 요청 - 쿠키값 (세션 ID) 포함하여 요청
      5. 서버가 세션ID 를 확인하고, 1번 요청과 같은 클라이언트임을 인지
구분 쿠키(Cookie) 세션(Session)
설명 클라이언트에 저장되며 작은 정보를 담아 서버 간 전송 가능한 데이터 파일 서버에 데이터가 저장되며 클라이언트를 식별하기 위해 사용
저장 위치 클라이언트 (웹 브라우저) 웹 서버
사용 예 사이트 방문의 "오늘 다시 보지 않기"와 같은 작업 로그인 정보 저장
만료 시점 쿠키 설정 시 만료일에 따라 설정 가능
(브라우저 종료시도 유지 가능)
다음 조건 중 하나가 만족될 경우 만료됨.
1. 브라우저 종료 시까지
2. 클라이언트 로그아웃 시까지
3. 서버에 설정한 유지기간까지 해당 클라이언트의 재요청이 없는 경우
용량 제한 브라우저 별로 다름 (크롬 기준)
- 하나의 데이터당 180개
- 하나의 쿠키당 4KB(4096byte)
개수 제한 없음
(단, 세션 저장소 크기 이상 저장 불가능)
보안 취약
(클라이언트에서 쿠키 정보를 쉽게 변경, 삭제 및 가로채기 당할 수 있음)
비교적 안전
(서버에 저장되기 때문에 상대적으로 안전)

쿠키와 세션 비교

3. JWT

  • JWT(Json Web Token): JSON 포맷을 이용하여 사용자에 대한 속성을 저장하는 Claim 기반의 Web Token
  • 일반적으로 쿠키 저장소를 사용하여 JWT를 저장한다.

JWT 사용 이유

  1. JWT 사용
    • 로그인 정보를 Server에 저장하지 않고, Client에 로그인 정보를 JWT 로 암호화하여 저장 → JWT 통해 인증/인가
    • 모든 서버에서 동일한 Secret Key 소유한다.
  2. JWT 장/단점
    • 장점
      • 동시 접속자가 많을 때 서버 측 부하 낮춤
      • Client, Sever 가 다른 도메인을 사용할 때
        • 예) 카카오 OAuth2 로그인 시 JWT Token 사용
    • 단점
      • 구현의 복잡도 증가
      • JWT 에 담는 내용이 커질 수록 네트워크 비용 증가 (클라이언트 → 서버)
      • 기 생성된 JWT 를 일부만 만료시킬 방법이 없음
      • Secret key 유출 시 JWT 조작 가능

JWT 사용 흐름

  1. Client가 username, password로 로그인 성공 시,
      • 서버에서 "로그인 정보"를 JWT로 암호화 (Secret Key 사용)
      • 서버에서 직접 쿠키를 생성해 JWT를 담아 Client 응답에 전달
      • 응답 Header에 다음 형태로 JWT 전달 
    Cookie cookie = new Cookie(AUTHORIZATION_HEADER, token); // Name-Value
    cookie.setPath("/");
    
    // Response 객체에 Cookie 추가
    res.addCookie(cookie);
    • 브라우저 쿠키 저장소에 자동으로 JWT 저장
  2. Client에서 JWT를 통한 인증 방법
      1. 서버에서 API 요청 시마다 쿠키에 포함된 JWT를 찾아서 사용 
    // HttpServletRequest 에서 Cookie Value : JWT 가져오기
    public String getTokenFromRequest(HttpServletRequest req) {
        Cookie[] cookies = req.getCookies();
        if(cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals(AUTHORIZATION_HEADER)) {
                    try {
                        return URLDecoder.decode(cookie.getValue(), "UTF-8"); // Encode 되어 넘어간 Value 다시 Decode
                    } catch (UnsupportedEncodingException e) {
                        return null;
                    }
                }
            }
        }
        return null;
    }
    1. Server
      • Client가 전달한 JWT 위조 여부 검증 (Secret Key 사용)
      • JWT 유효기간이 지나지 않았는지 검증
      • 검증 성공시, JWT에서 사용자 정보를 가져와 확인
Comments