개발지식 먹는 하마 님의 블로그
쿠키 Cookie와 세션 Session 그리고 토큰 Token 본문
🍪 Cookie
클라이언트에 저장되는 작은 데이터
서버는 무상태 Stateless이기 때문에 클라이언트의 상태를 보존하지 않는다.
따라서, 쿠키를 사용해 사용자의 상태 또는 세션을 유지한다.
🍪 Cookie를 사용하는 과정
- 클라이언트가 로그인을 시도한다.
- 로그인에 성공하면, 서버는 쿠키를 만들고 Set-Cookie 헤더를 통해 응답에서 쿠키를 함께 보낸다.
- 클라이언트는 웹 브라우저 내에 있는 쿠키 저장소에 받은 쿠키를 저장한다.
- 이후의 요청마다 클라이언트는 가지고 있는 쿠키를 요청에 함께 보낸다.
🍪 Cookie의 단점
쿠키는 탈취되기 쉬우며 한번 탈취된 정보는 반영구적으로 사용할 수 있다.
또한, Client가 임의로 값을 변경하면 다른 유저로 인식할 수 있다.
- 쿠키에 중요한 값을 저장하지 않는다.
- 암호화된 Token을 저장하고 Token은 서버에서 관리한다 ➡️ like JWT
- 탈취 의심 시, 강제 만료시킨다.
📛 Session - 중요한 건 서버가 관리할게!
서버에서 중요한 정보를 보관하는 방법
결국 보안 문제를 해결하기 위해서 중요한 정보는 모두 서버에 저장해야한다.
이를 위해 사용되는 방법이 바로 세션이다.
📛 Session을 사용하는 과정
- 클라이언트가 로그인을 시도한다.
- 로그인에 성공하면, 서버는
쿠키를 만들고➡️ Session Id를 생성하고 Session 저장소에 저장한다. - 상태유지를 위해 쿠키에 Session Id를 담아 클라이언트에게 보낸다.
- 클라이언트는 이후의 요청에 쿠키의 Session Id를 전달한다.
- 서버는 Session 저장소에서 해당 Session Id를 조회한다.
클라이언트가 쿠키값을 변조해도 문제가 없고, 탈취된 경우 중요한 정보가 담겨있지 않아 보안상 큰 문제가 없다.
📛 Session의 단점
메모리를 사용하기 때문에 세션이 많아지면 메모리 리소스 부족으로 인한 장애가 발생할 수 있다.
- 세션의 만료시간을 설정한다. (Default 30분)
🏷️ Token
사용자 또는 시스템의 신원과 권한을 증명,
요청의 유효성을 검증하는데 사용되는 디지털 문자열
위조 방지를 목적으로 한다.
- 클라이언트에 저장되어 서버의 부담을 덜 수 있다.
- 확장성이 뛰어나다
- 고유한 서명 = 시크릿 키를 통해 위조 여부를 쉽게 알 수 있다.
- 시크릿 키를 통해 위조 여부를 쉽게 알 수 있다.
Token은 Header, Payload, Signature 구조로 이루어진다.
각 구조에 담기는 내용은 다음과 같다.
구조 | 종류 | 예시 |
Header | 해싱 알고리즘 | "alg" : "HS256" |
토큰 타입 | "typ" : "JWT" | |
Payload | Registered Claims 미리 정의됨 |
|
발행자 iss | ||
발행시간 iat | ||
만료시간 exp | ||
토큰 고유 식별자 jti | ||
제목 sub | ||
Public Claims 사용자 정의 가능 |
공개용 정보 전달 | |
Private Claims 사용자 지정 |
당사자들 간의 정보 공유 | |
Signature | HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret key ) |
|
Signature은 header와 payload를 시크릿 키로 서명하여 header에 정의한 알고리즘을 활용해 암호화한다.
🏷️ Token을 사용하는 과정
- 클라이언트가 로그인을 시도한다.
- 로그인에 성공하면, 서버는 사용자 정보를 바탕으로 Token을 생성하고 Cookie에 담아 전달한다.
- 클라이언트는 이를 저장 후 요청마다 Authorization Header 에 JWT 를 담아
- 서버는 전달받은 JWT의 서명을 검증하고, 토큰이 위조되지 않았고 유효한지 확인한다.
- 검증에 성공하면, 토큰 내부의 사용자 정보를 활용해 요청을 처리한다.
🏷️ JWT를 선호하는 이유
앞서 언급된 내용과 같이
세션은 메모리를 사용하기 때문에 세션이 많아지면 세션 저장소의 메모리 리소스 부족으로 인한 장애가 발생할 수 있다.
또한, 매 요청마다 세션 저장소에서 Session ID를 조회해야 하는데, 조회 부하가 증가하게 된다.
반면, JWT는 해당 유저가 제시한 토큰의 서명과 만료 여부만 검증하면 되기 때문에 추가 조회가 필요하지 않다.
🏷️ JWT의 단점
- Payload 는 암호화 된 것이 아니라 민감한 정보를 다루지 못한다 .
- Token 의 길이가 길어서 트래픽이 증가하면 네트워크에 부하가 증가한다 .
- 클라이언트 측에서 Token 을 관리하기 때문에 탈취당하면 대처하기 어렵다 .
Access Token과 Refresh Token을 사용한다.
✅ Access Token과 Refresh Token
보안을 위해 Access Token의 유효 시간을 짧게 설정한다.
따라서 Access Token이 만료되었다면 Refresh Token으로 재발급을 요청하고
서버로부터 Access Token을 재발급 받는다.
보안을 강화하기 위해 Refresh Token은 재발급 시 마다 갱신하거나 1회용으로 사용하는 경우도 있다.
서버는 Refresh Token의 유효성 및 사용 여부를 반드시 검증해야 한다.
🔒 JWT 사용 시, 주의해야 하는 보안 사항
1) alg : none 공격
alg : none이 통과되는 곳이 종종 있기 때문에 none으로 변경 후 전송하는 경우가 있다.
(최신 라이브러리를 사용하면 걱정할 필요가 없다.)
2) 변환이 쉽다.
DECODING이 매우 쉽기 때문에 최소한의 정보만 넣어야 한다.
3) 시크릿키
시크릿키를 대충 쓰면 절대 안 된다!
예측이 매우 쉽기 때문이다.
- 시크릿키를 길게 작성한다.
- 절대 공유하지 않는다.
- 생성용키/검증용키 2개를 사용한다.
위의 3가지 방법을 참고하면 좋다.
4) Token 탈취
- HttpOnly cookie와 같이 보안이 철저한 저장소를 사용한다.
- 블랙리스트를 만들어 관리한다. -> JWT 사용의 장점 소멸
- 짧은 유효기간 (5분) -> 재발급을 위한 Refresh Token이 필요하다.
- Refresh Token Rotation 사용 (Refresh Token은 항상 1회용!)
[참고 자료]
https://www.youtube.com/watch?v=XXseiON9CV0&ab_channel=%EC%BD%94%EB%94%A9%EC%95%A0%ED%94%8C
'Web' 카테고리의 다른 글
공통 로직 처리를 위한 Filter, Interceptor 그리고 AOP (0) | 2025.04.21 |
---|---|
로딩 전략과 Fetch Join 그리고 Proxy (0) | 2025.04.17 |
DTO (Data Transfer Object) (0) | 2025.03.31 |
웹 서비스 구조 및 흐름을 비유와 함께 이해하기 (0) | 2025.03.20 |
REST API와 RESTful API (0) | 2025.03.20 |