인증(Authentication)
누구냐?
: 사용자가 주장하는 신원을 확인하는 과정
- 보통 id & 비밀번호와 같은 자격 증명을 기반으로 수행됨
인가(Authorization)
무엇을 할 수 있냐?
: 사용자가 특정 리소스나 기능에 접근할 수 있는 권한을 부여하는 과정
- 인증을 통해 사용자가 누구인지 확인 후, 해당 사용자가 어떤 작업을 할 수 있는지 결정
인증과 인가
- 인증은 이 사람이 누구인지 확인하는 과정이라면,
인가는 이 사람이 무엇을 할 수 있는지를 결정하는 과정
e.g.
[인증] 웹 사이트 로그인
[인가] 사용자가 해당 사이트에서 실행할 수 있는 작업을 결정
인증 방식의 종류
1) 세션 기반 인증
서버에서 클라이언트 정보를 기억

- 사용자가 시스템에 로그인할 때
서버가 세션 ID를 생성하고, 이를 클라이언트에게 전달
- 이후 요청에서 클라이언트를 식별하고 인증하는 방식
- 사용자 인증 정보를 서버 측에서 관리하고,
클라이언트는 세션 ID만으로 지속적으로 인증을 유지하는 방식
[세션 기반 인증의 흐름]
- 사용자가 로그인 요청
- 서버가 세션 생성
인증이 성공하면 서버는 고유한 세션 ID를 생성하고,
이를 서버 내에 저장
세션은 서버 측 세션 스토리지 (메모리 or 데이터베이스)에 저장될 수 있음
- 세션 ID 전달
서버는 세션 ID를 쿠키 / HTTP 헤더를 통해 클라이언트에 전달
(일반적으로 쿠키 사용)
- 클라이언트가 세션 ID를 사용하여 요청
이후 클라이언트가 서버에 요청을 보낼 때마다. 세션 ID가 포함된 쿠키를 함께보냄
서버는 세션ID를 통해 사용자가 누구인지 식별할 수 있음
- 서버에서 세션 정보 확인
서버는 받은 세션 ID를 기반으로 , 서버 측에 저장된 사용자의 로그인 상태, 권한 정보를 찾아 요청을 처리
- 로그아웃
사용자가 로그아웃 할 때, 서버는 클라이언트에게 전달한 세션을 삭제
클라이언트의 세션 쿠키도 삭제하여 세션을 만료 시킴
[장점]
- 인증정보가 서버에서 관리
클라이언트 측에 사용자 정보를 저장할 필요 없이 세션 ID만 가지고 있으면 됨
- 보안
세션 ID는 랜덤하고 고유한 값 → 유출되지 않는 한 세션 하이재킹 방지 가능
서버에서 세션을 관리하므로 서버에서 세션 종료나 관리 가능
- 세션 타임아웃
서버에서 세션 관리
세션은 일정 시간 지나면 자동 만료되도록 설정할 수 있어 보안 강화 가능
[단점]
- 서버 부하
세션 데이터가 서버 메모리나 DB에 저장되어 서버 자원을 소모
많은 사용자의 동시 접속 → 서버의 메모리 / 저장소 부담
- 세션 유지 문제
서버가 재시작되면 모든 세션 정보가 사라지게 됨
- 확장성 문제
세션을 여러 서버에 공유하려면 세션 스토리지를 분산시켜야 함
[e.g.] 로드 밸런싱이 필요한 경우 여러 서버에서 세션을 공유하는 방안을 마련해야 하므로 복잡도 증가
[c.f.] 로드 밸런싱?
여러 대의 서버에 들어오는 트래픽(요청)을 고르게 분산시켜서, 시스템의 성능과 안정성을 높이는 기술
쿠키
세션 ID를 쿠키에 저장하여 서버에 전달하는 방식이므로, 사실상 쿠키도 세션 기반 인증의 한 형태로 볼 수 있음
[세션과 쿠키의 관계]
쿠키는 세션 ID를 저장하는 매개체
- 쿠키는 클라이언트 측에 저장되지만, 실제 인증 정보는 서버에 저장됨
- 서버는 세션 저장소의 사용자의 세션 상태를 관리하고, 쿠키에 저장된 세션 ID를 통해 인증을 처리
- 서버에서 클라이언트를 인증할 때 주로 세션 ID를 쿠키에 저장하고,
클라이언트는 이후 모든 요청에서 해당 세션 ID를 포함한 쿠키를 서버에 전송
2) 토큰 기반 인증 (JWT, JSON Web Token)
클라이언트에서 사용자의 정보를 가지고 있음
![업로드중..]()
- 인증 후 서버에서 토큰을 발급하고, 클라이언트는 해당 토큰을 사용하여 요청을 보냄
- 서버는 이 토큰을 검증하여 인가 여부를 확인
- JWT는 상태 비저장(stateless) 인증 방식으로, 서버는 세션 정보를 저장하지 않고 클라이언트가 발급받은 토큰을 통해 인증과 인가를 처리
- 리프레시 토큰
JWT의 만료 시간이 짧기 때문에, 만료된 JWT를 갱신하기 위해 리프레시 토큰을 사용
리프레시 토큰은 보통 HTTP-only 쿠키에 저장되어 보안이 강화됨
리프레시 토큰을 이용해 새로운 액세스 토큰을 발급받을 수 있음
[JWT 구조]
// .으로 구분된 3가지 부분
// Base64Url로 인코딩 하여 전달
<헤더>.<페이로드>.<서명>
// 1. 헤더 :JWT의 타입과 알고리즘을 지정 (HS256, RS256)
{
"alg": "HS256",
"typ": "JWT"
}
2. 페이로드 :JWT에 포함될 클레임(claim)을 담고 있음
[클레임]
1) 등록된 클레임(Registered Claims): JWT 표준에 정의된 미리 정의된 클레임 (예: iss, exp, sub, aud 등)
2) 공개 클레임(Public Claims): 사용자 정의 클레임, 충돌을 방지하기 위해 URI 형식으로 정의
3) 비공개 클레(Private Claims): 애플리케이션에서 특정 용도로 정의한 클레임
{
"sub": "1234567890", // 토큰의 주체 (subject)로 주로 사용자의 id
"name": "John Doe",
"iat": 1516239022 // 토큰 발급 시간 (Issued At) <-> exp: 토큰 만료 시간 (Expiration)
}
3. 서명: 헤더 & 페이로드를 결합하여 비밀 키를 사용해 서명한 값
// 이를 통해 JWT의 데이터가 변조되지 않았음을 확인할 수 있음
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
[장점]
- 상태 비저장 (Stateless)
서버는 세션 정보를 저장하지 않으며,
모든 정보를 JWT 토큰 내에 포함시켜 클라이언트 측에서 관리
서버가 세션을 저장하지 않으므로 서버의 확장성이 높음
-
스케일링
서버가 여러 대일 때 세션 공유 문제를 피할 수 있음
→ 각 서버가 독립적으로 인증을 처리할 수 있음
-
보안
서명된 JWT는 변조되지 않았음을 보장함
서명은 비밀 키로 생성되므로 서버만이 그 키를 알고 있고, 클라이언트는 이를 알지 못함
HTTPS를 통해 토큰을 전송하면 중간자 공격(Man-in-the-Middle)을 방지할 수 있음
-
확장성
JWT는 다양한 환경과 플랫폼에서 호환성이 좋음
RESTful API와 같은 분산 시스템에서 유용함
[단점]
- 토큰 유출 위험
클라이언트가 토큰을 저장 → 토큰이 유출되면 세션 하이재킹 발생 가능
- 토큰 크기
jwt는 헤더와 페이로드를 포함하므로 세션 기반 인증보다 크기가 큼
요청마다 보내는 데이터 양이 커질 수 있음
- 서버 측의 키 관리
jwt는 비밀키 또는 공개키로 서명을 사용하므로 키 유출 시 보안에 큰 위협이 됨