웹 애플리케이션의 보안 체계를 이해하는 데 필요한 두 가지 핵심 개념은 '인증'과 '인가'입니다.
우리가 개발시 흔히 SecurityConfig를 구성하거나 API를 구현할 때 Authentication과 Authorization을 사용하지만 두 단어가 서로 비슷하여 종종 혼동됩니다.
하지만, 인증과 인가의 개념을 매우 다릅니다.
인증은 사용자의 신원을 확인하는 과정입니다.
일반적으로 로그인 즉, LoginId와 LoginPw를 통해 계정의 소유를 증명합니다.
서버는 사용자가 계정의 소유자를 증명하기 전까지는 아무 권한도 부여하지 않습니다.
예를 들어, 웹사이트에 로그인할 때 우리는 자신의 아이디와 비밀번호를 입력합니다.
서버는 이 정보를 확인하여 우리가 주장하는 대로 해당 계정의 소유자임을 판단합니다.
인증 후에 이루어지는 과정으로, 해당 사용자가 어떤 서비스나 데이터에 접근하거나 수정할 수 있는 권한이 있는지 결정하는 것입니다.
예를 들어, 관리자 페이지에 접근하려고 시도했을 때 시스템은 당신이 관리자 권한을 가진 사람인지 확인합니다. 만약 당신이 일반 사용자라면, 그 페이지에 접근할 수 없게 됩니다.
또한, 사용자의 로그인 상태 유지에도 Authorization이 사용됩니다.
사용자가 서버에 인증을 받으면 서버는 세션 또는 토큰을 제공합니다.
이후 클라이언트가 요청을 보낼 때 마다 세션 또는 토큰을 함께 보내어 인증된 사용자임을 증명 합니다.
세션 기반 인증은 전통적인 방식으로 가장 널리 사용되는 방식입니다.
이 방식에서 클라이언트는 서버에 로그인 요청을 보내고, 서버는 데이터베이스를 조회하여 사용자가 유효한지 확인합니다.
유효한 경우 서버는 고유한 ID를 생성하고 이를 세션이라고 합니다.
JWT(JSON Web Token) 는 웹 표준(RFC 7519)으로서 두 개체 사이에서 JSON 객체를 사용하여 정보를 안전하게 전송할 수 있는 방법을 정의합니다.
xxxxx.yyyyy.zzzzz 같은 형태를 가지면 .을 기준으로 3가지 부분으로 나뉩니다.
여기서 xxxxx, yyyyy, zzzzz 각각은 Base64Url로 인코딩된 문자열을 나타내며, 각각 Header, Payload, Signature라고 부릅니다.
JWT의 첫 번째 부분은 Header입니다. 이 부분은 토큰의 타입과 사용된 해시 알고리즘 정보를 담고 있습니다.
{
"alg": "HS256", //해싱 알고리즘(예: HS256)
"typ": "JWT" // 토큰 타입
}
Payload 또는 클레임 셋(Claim set)은 실제 JWT가 전달하려는 데이터가 포함되어 있는 부분입니다. 클레임(Claim)이란 엔티티(일반적으로 사용자)와 추가 정보에 대한 선언입니다.
클레임에는 등록된 클레임(Registered Claim), 공개 클레임(Public Claim), 비공개 클레임(Private Claim) 등 세 가지 종류가 있습니다.
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
이 부분은 토큰의 무결성을 보장하기 위해 사용됩니다.
서버는 이 서명을 사용하여 토큰이 변조되지 않았음을 확인하고, 해당 토큰이 신뢰할 수 있는 출처에서 발급된 것임을 검증합니다.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
생성된 JWT는 jwt.io 링크에서 디코딩 할 수 있습니다.
세션 기반 인증은 주로 웹 기반 애플리케이션에서 많이 사용됩니다. 이 방식은 서버가 클라이언트의 상태 정보를 계속해서 추적하기 때문에, 사용자의 선호 설정, 쇼핑 카트 등 복잡한 기능을 구현하는데 적합합니다.
JWT는 주로 RESTful API에서 인증을 위해 많이 사용됩니다. Stateless한 구조로 인해 여러 서비스 간에 자유롭게 데이터를 교환할 수 있어 마이크로서비스 아키텍처와 같은 분산 시스템에서 많은 장점을 가집니다.
두 방식 모두 각각의 환경과 요구사항에 따라 적절히 선택하여 사용하는 것이 중요합니다.