[Codeit]/Spring 백엔드 10기 위클리페이퍼

[13] 인증(Authentication)과 인가(Authorization)

uzlru 2026. 5. 20. 17:43

01. 세션 기반 인증과 토큰 기반 인증

1. 세션 기반 인증 (Stateful Architecture)

세션 기반 인증은 서버가 사용자의 인증 정보를 직접 관리하는 방식을 뜻한다. 즉, 세션 기반 인증 방식은 사용자가 로그인에 성공하면, 서버가 메모리(DB / Redis)에 세션 저장소를 생성하고 사용자 정보를 저장하는 방식을 의미한다.

 

이렇게 저장된 사용자 정보는 무작위 문자열인 세션 ID에 의해 식별되며, 클라이언트는 해당 세션 ID를 브라우저의 쿠키에 저장한다. 클라이언트는 매 요청마다 HTTP 헤더에 쿠키를 담아 보내며, 서버는 HTTP 요청 헤더에 포함된 세션 ID를 기반으로 세션 저장소에서 사용자를 조회하여 인증을 수행한다.

 

또한 이러한 세션 기반 인증은 크게 다음과 같은 세 가지 보안 고려사항을 갖는다.

 

1. 세션 하이재킹 (Session Hijacking)

세션 하이재킹이란 HTTP 프로토콜이 세션 ID의 유효성만을 확인한다는 점을 이용하여, 공격자가 네트워크 스니핑이나 XSS를 통해 사용자의 세션 ID를 탈취하여 정상 사용자로 위장하는 공격 기법을 뜻한다. 즉, 공격자는 로그인에 성공한 사용자가 서버로부터 발급받은 합법적인 세션 ID를 중간에서 가로채, 사용자의 권한을 도용하는 공격을 의미한다.

 

이러한 세션 하이재킹은 암호화된 통신 HTTPS에서만 쿠키를 서버로 전송하는 Secure 옵션악성 자바스크립트 코드의 쿠키 접근을 완전히 차단하는 HttpOnly 옵션을 통해 방어할 수 있다.

 

2. CSRF (Cross-Site Request Forgery)

CSRF란 사이트 간 요청 위조로, 브라우저가 특정 도메인으로 요청을 보낼 때 해당 도메인의 쿠키를 자동으로 첨부하는 특성을 이용하여, 용자가 악성 링크를 클릭하도록 유도하여 의도치 않은 비즈니스 로직(비밀번호 변경, 송금 등)을 실행하는 공격 기법을 뜻한다. 즉, 사용자의 브라우저가 가진 쿠키 자동 전송 특성을 악용하여 사용자의 손으로 공격 요청을 보내게 만든는 공격을 의미한다.

 

이러한 CSRF는 크로스 사이트 요청 시, 쿠키 전송 범위를 제한하는 쿠키의 SameSite 설정서버 세션에 저장된 CSRF 토큰과 요청으로 들어온 CSRF 토큰이 일치하는지 비교하는 검증을 통해 방어할 수 있다.

 

3. 분산 환경에서의 서버 확장성 (Scale-out Issues)

세션 기반 인증 방식은 인증 정보가 서버 메모리에 종속되기 때문에, 서버를 여러 대 배치하는 분산 환경에서 세션 정합성 불일치 문제가 발생한다. 세션 정합성 불일치 문제란 분산 환경(Scale-out) 환경에서 새로운 서버의 메모리에 사용자의 세션 정보가 존재하지 않아 사용자의 로그인 상태가 유지되지 않고 로그아웃되는 현상을 뜻한다.

 

이러한 세션 정합성 불일치는 로드 밸런서가 특정 사용자의 모든 요청을 첫 요청을 처리했던 서버로 전송하는 Sticky Session여러 서버가 메모리에 저장된 세션 데이터를 실시간으로 복제하여 모든 서버가 동일한 세션 데이터를 갖도록 하는 세션 클러스터링, 서버 내부 메모리에 세션을 저장하는 대신 모든 서버가 공통으로 접근할 수 있는 외부 저장소를 따로 구축하는 공유 세션 스토리지 구축을 통해 방어할 수 있다.

 

특히 공유 세션 스토리지 구축 기법은 부하 분산 및 네트워크 대역폭 낭비와 같은 문제점을 갖는 앞선 두 기법과 달리, 서버를 수십 대 확장하더라도 세션 정합성이 완벽하게 유지될 뿐만 아니라 특정 애플리케이션 서버가 다운되어도 세션 데이터가 유실되지 않는 고가용성을 보장한다. 때문에 공유 세션 스토리지 구축 기법은 현대 백엔드 인프라의 표준 설계로 자리 잡았으며, 주로 Redis나 Memcached와 같은 인메모리 데이터베이스를 활용하여 구축한다.

 

2. 토큰 기반 인증 (Stateless Architecture)

토큰 기반 인증은 서버가 상태를 유지하지 않고, 클라이언트가 직접 인증 정보를 관리하는 방식을 뜻한다. 즉, 토큰 기반 인증 방식은 사용자가 로그인에 성공하면, 클라이언트가 로컬 저장소 및 쿠키에 식별 정보와 권한 등이 포함된 JSON 데이터와 토큰을 저장하는 방식을 의미한다. 이러한 토큰 기반 인증 방식에는 주로 JWT(JSON Web Token)이 사용된다.

 

토큰이란 특정 서버의 비밀키로 서명된 데이터 인증서로, 클라이언트는 매 요청마다 HTTP 헤더에 토큰을 담아 서버에 전송하며, 서버는 세션 저장소 조회없이, 토큰의 유효성을 검증하여 인증을 처리한다.

 

또한 이러한 토큰 기반 인증 방식은 크게 다음과 같은 세 가지 보안 고려사항을 갖는다.

 

1. XSS (Cross-Site Scripting)

XSS란 웹 사이트에 악성 스크립트를 삽입하는 공격 기법을 뜻한다. 즉, 공격자가 웹 사이트에 악성적인 자바스크립트 코드를 삽입하여 사용자의 토큰을 가로채, 토큰이 만료되기 전까지 사용자의 권한을 도용하는 공격 기법을 의미한다.

 

또한 한 번 발급된 토큰은 서버의 제어권을 벗어나기 때문에, 사용자가 로그아웃을 요청하더라도 만료 시간이 되기 전까지 토큰의 유효성은 사라지지 않는다. 즉, 서버가 특정 토큰을 강제로 만료시키는 메커니즘이 제공되지 않는다.

 

이러한 문제점을 해결하기 위해, 실무에서는 보통 두 종류의 토큰을 혼합하여 사용하는 듀얼 토큰 아키텍처를 사용한다. 사용자는 Access Token을 통해서만 서버에게 API 요청을 전송할 수 있으며, 서버는 Refresh Token을 관리하여 공격자의 토큰 탈취로부터 사용자를 보호한다.

 

토큰 종류   유효 기간 저장소
Access Token 실제 API 요청을 보낼 때 인증 헤더에 담는 토큰 30분 - 1시간 내외 클라이언트 측 저장소
Refresh Token 새로운 Access Token을 발급받기 위해 사용하는 토큰 2주 - 한 달 서버 측 인메모리 저장소

 

3. 세션 기반 인증 vs 토큰 기반 인증

  세션 기반 인증 토큰 기반 인증
인증 상태 저장소 서버 측 인메모리 클라이언트 측 메모리
서버 구조 아키텍처 상태 유지 (Stateful) 상태 유지 안 함 (Stateless)
클라이언트 전송 방식 HTTP 요청 시, 쿠키(Cookie) 헤더에 자동 포함 HTTP Authorization 헤더에 토큰을 수동 첨부
서버 확장성
(Scale-out)
불편함 매우 용이
사용자 강제 제어 및 무효화 서버에서 세션 삭제를 통한 무효화 가능 원칙적으로 불가능
주요 보안 취약점 CSRF 공격, 세션 하이재킹 XSS 공격을 통한 토큰 탈취 위험
네트워크 트래픽 부담 낮음 (세션 ID 문자열 송신) 높음 (JSON 데이터 및 토큰 송신)
적합한 시스템 환경 단일 도메인 중심의 전통적인 웹 서비스 멀티 도메인, 모바일 앱, MSA(마이크로서비스) 환경

 


 

02. OAuth 2.0 아키텍처와 Authorization Code Grant 흐름

1. OAuth 2.0 아케텍처

OAuth란 애플리케이션이 사용자의 비밀번호를 직접 받지 않고, 구글 및 네이버와 같은 제3의 서비스로부터 인증 및 인가 권한을 안전하게 위임받기 위한 개방형 표준 프로토콜을 뜻한다. 이러한 OAuth 아키텍처는 크게 4가지의 구성 요소를 갖는다.

 

주요 컴포넌트  
자원 소유자
(Resource Owner)
실제 서비스 사용자로, 애플리케이션이 제3 서비스 데이터에 접근할 수 있도록 권한을 승인하는 주체
클라이언트
(Client)
자원 서버의 권한을 위임받아 외부 자원(사용자 정보)을 이용하려는 애플리케이션
인증 서버
(Authorization Server)
사용자를 인증하고, 클라이언트의 접근을 승인하여 Access Token을 발급하는 서버
자원 서버
(Resource Server)
보호된 사용자의 자원을 호스팅하는 서버로, Access Token을 검증하여 자원을 제공

 

 

2. 인가 코드 승인 방식 (Authorization Code Grant )의 메커니즘

인가 코드 승인 방식 메커니즘 실행 주체  
클라이언트 접근 및 로그인 요청 사용자 소셜 미디어(구글, 네이버, 카카오 등)를 통한 로그인 시도
인증 요청 클라이언트 사용자의 브라우저를 인증 서버의 인증 페이지(로그인 URL)로 리다이렉트
사용자 인증 및 동의 사용자 인증 서버 로그인 및 클라이언트의 사용자 정보 접근 동의 수행
인가 코드 발급 인증 서버 사전에 등록된 클라이언트의 URL로 사용자의 브라우저를 리다이렉트
인가 코드 전달 인증 서버 리다이렉트와 동시에 클라이언트의 백엔드 서버로 인가 코드 전달
Access Token 요청 백엔드 서버 브라우저없이 인증 서버에 직접 API 요청 전송
Access Token 발급 인증 서버 클라이언트의 비밀키(Client Secret) 유효성 검증 및 Access Token 발급
자원 접근 백엔드 서버 HTTP 헤더에 Access Token을 담아 자원 서버에 전송하여 사용자 정보 접근

 

3. 인가 코드 단계의 필요성

만약 인증 서버가 클라이언트 브라우저에 인가 코드 대신 Access Token을 발급할 경우, 브라우저의 히스토리 및 네트워크 스니핑, 브라우저 확장 프로그램 등에 의해 클라이언트의 토큰 유출 위험성이 증가한다. 하지만 프론트엔드 계층에 일회성 비밀번호인 인가 코드를 노출 시키고, 해당 인가 코드를 통해 백엔드 서버 통신을 통해서만 Access Token을 송수신 할 경우 토큰의 유출 위험성은 현저하게 하락한다. 따라서 백엔드 환경에서 인가 코드를 활용하여, 클라이언트의 비밀키와 Access Token을 교환하는 설계는 보안의 신뢰성을 극대화한다.