토큰(Token)은 사용자의 인증 및 권한을 확인하기 위해 발급되는 문자열로, 보안 및 인증 시스템에서 중요한 역할을 한다.
특히 웹 애플리케이션에서 세션(Session)과 함께 사용자 인증을 관리하는 주요 방식이다.
1) 토큰의 필요성
웹 서비스에서 사용자의 인증을 유지하기 위한 전통적인 방식은 세션(Session) 이었지만, 다음과 같은 문제점이 있었다.
✅ 서버 부하 증가
- 세션은 서버가 직접 사용자 정보를 저장해야 하므로, 사용자가 많아질수록 서버 부하가 증가.
- 여러 개의 서버를 사용할 경우, 세션을 공유해야 하는 문제가 발생.
✅ 분산 환경에서의 문제
- 여러 서버에서 서비스하는 경우, 특정 서버에 저장된 세션 정보를 다른 서버에서 사용할 수 없음.
✅ 확장성 부족
- 서버가 인증 정보를 관리해야 하므로, 확장성이 떨어짐.
이러한 문제를 해결하기 위해 등장한 것이 토큰 기반 인증(Token-Based Authentication) 이다.
2) 토큰의 주요 특징
- 서버에서 상태를 저장하지 않음(Stateless)
- 세션과 달리 서버가 직접 사용자 정보를 저장하지 않음.
- 따라서 확장성과 성능이 뛰어남.
- JWT(JSON Web Token) 사용
- 가장 널리 사용되는 토큰 형식으로, JSON 데이터를 인코딩하여 인증 정보 포함.
- 토큰 만료 시간 설정 가능
- 특정 시간이 지나면 토큰이 자동으로 만료되도록 설정 가능.
- 서버 간 인증 가능
- API, 마이크로서비스, 모바일 앱 등 다양한 환경에서 인증할 수 있음.
3) 토큰의 종류
- 액세스 토큰(Access Token)
- 사용자가 API에 요청을 보낼 때, 인증을 위해 포함하는 토큰.
- 보통 JWT 형식으로 제공되며, 일정 시간이 지나면 만료됨.
- 보안 강화를 위해 HTTP 헤더의 Authorization 필드에 포함하여 전송.
- Authorization: Bearer eyJhbGciOiJIUzI1...
- 리프레시 토큰(Refresh Token)
- 액세스 토큰이 만료되었을 때, 새 액세스 토큰을 발급받기 위한 용도.
- 일반적으로 서버에 저장되며, 액세스 토큰보다 긴 유효 기간을 가짐.
- 주로 OAuth2.0과 같은 인증 방식에서 사용됨.
4) 토큰의 동작 방식
- 로그인 요청
- 사용자가 ID/PW를 입력하여 로그인 요청.
- 서버에서 사용자 인증 후 토큰 발급
- 로그인 성공 시 액세스 토큰과 리프레시 토큰을 발급.
- 액세스 토큰은 일정 시간이 지나면 만료됨.
- 사용자가 API 요청 시 토큰 전송
- 클라이언트는 API 요청 시 Authorization: Bearer <토큰> 헤더를 포함.
- 서버는 해당 토큰을 검증하여 요청을 처리.
- 토큰 만료 시 리프레시 토큰 사용
- 액세스 토큰이 만료되면, 클라이언트는 리프레시 토큰을 이용하여 새 액세스 토큰을 요청.
- 로그아웃 또는 만료 시 토큰 삭제
- 사용자가 로그아웃하면 토큰이 무효화됨.
5) JWT(JSON Web Token)
토큰 기반 인증에서 가장 많이 사용하는 방식이 JWT 이다.
JWT는 사용자 인증 정보를 포함하는 JSON 기반의 토큰으로, 세 부분으로 구성된다.
- JWT 구조
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMjMiLCJyb2xlIjoiYWRtaW4iLCJleHAiOjE2ODMwNzEyMDB9.LYpOkDs-KD...
JWT는 Header(헤더), Payload(페이로드), Signature(서명) 세 부분으로 나뉜다.
구성 요소 설명
Header (헤더) | 암호화 알고리즘 정보 포함 (예: HS256, RS256) |
Payload (페이로드) | 사용자 정보(클레임) 포함 (예: userId, role, exp) |
Signature (서명) | 토큰의 무결성을 검증하기 위한 서명 |
- JWT 예제
{
"alg": "HS256",
"typ": "JWT"
}
.
{
"userId": "123",
"role": "admin",
"exp": 1683071200
}
.
Signature
- JWT 장점
✅ 서버 상태 저장 불필요 (Stateless)
✅ 빠른 인증 처리
✅ 기본적으로 암호화된 데이터 포함 가능
- JWT 단점
❌ 토큰이 탈취되면 보안 위험
❌ 서버에서 토큰을 직접 폐기할 수 없음
❌ 토큰 길이가 길어질 수 있음
6) OAuth2.0과 토큰
OAuth2.0은 외부 서비스에서 안전하게 인증을 수행하는 프로토콜이다.
로그인할 때 "Google로 로그인", "Facebook으로 로그인" 같은 방식이 OAuth2.0을 사용한 예시이다.
OAuth2.0에서는 액세스 토큰과 리프레시 토큰을 사용하여 인증을 수행한다.
- OAuth2.0 인증 과정
- 사용자가 Google 로그인 요청
- Google이 인증 후 액세스 토큰 발급
- 사용자는 액세스 토큰을 이용하여 API 요청
- 토큰이 만료되면 리프레시 토큰으로 새로운 액세스 토큰 발급
7) 토큰과 세션(Session) 비교
구분 세션(Session) 토큰(Token)
저장 위치 | 서버 (메모리, DB) | 클라이언트 (JWT, 로컬스토리지) |
확장성 | 서버 부하 증가 | 서버 부담 적음 (Stateless) |
보안 | 세션 ID 탈취 가능 | 토큰 유출 시 보안 위험 |
유효 시간 | 서버에서 직접 관리 | 만료 후 재발급 필요 |
인증 방식 | 서버에서 검증 | 토큰을 활용한 자체 검증 |
8) 토큰 보안 위험 및 해결책
- 토큰 탈취 방지
✅ HTTPS 사용: 토큰이 네트워크에서 탈취되지 않도록 SSL/TLS 적용
✅ HttpOnly 쿠키 사용: JavaScript에서 접근하지 못하도록 설정
- 토큰 유효기간 관리
✅ 짧은 액세스 토큰 유효 기간 설정
✅ 리프레시 토큰을 이용한 갱신 방식 사용
- 토큰 서명 검증
✅ JWT 사용 시 서명 검증 필수
✅ HMAC, RSA 등의 암호화 알고리즘 적용
9) 결론
토큰은 웹 인증에서 세션을 대체하는 방식으로, 특히 JWT와 OAuth2.0이 많이 사용된다.
서버 부담을 줄이고 확장성을 높일 수 있지만, 보안 관리(토큰 탈취 방지, 짧은 만료 시간 설정 등) 가 필수적이다.
✅ 세션과 토큰 중 어떤 것이 더 적합한지는 서비스 환경에 따라 다름.