토큰(Token) 인증 방식
이전 포스팅에서 언급했든 HTTP 프로토콜은 무상태성(stateless)의 특징을 갖기에 모든 url요청은 독립적이다. 그렇기에 우리는 클라이언트가 한 인증을 유지해주기 위한 장치가 필요한데 이때 사용되는것이 세션, 쿠키, 토큰 이 존재하며 보안을 강화하기 위해 토큰 사용하게 된다.
토큰 기반 인증은 세션과 쿠키와는 달리 상태 정보를 서버에 저장하지 않고, 클라이언트가 토큰을 포함하여 요청을 보내면 서버에서 토큰을 검증하여 인증을 처리한다. 토큰은 주로 OAuth나 JWT(JSON Web Token)와 같은 기술을 사용하여 구현한다.
JSON Web Token(JWT)
JSON Web Token(JWT)
RFC 7519 웹 표준이며, JSON 객체를 사용해 토큰 자체의 정보를 저장하고있는 웹 토큰이다.
JWT 생성
우선 클라이언트가 인증이 성공하면 Spring Security에서 인증이 성공하면 토큰을 생성해준다. 해당 토큰에는 이름, id, 토큰 만료시기 등이 인코딩 되어 저장된다. 하지만 비밀번호 등과 같이 민감한 정보는 담지 않는다. 이는 인코딩된 토큰의 정보는 디코딩되기 쉽기 때문이다.
그림을 보면 클라이언트가 Basic Authentication* 요청을 보낸다. 서버는 해당 요청에 있는 인증정보를 확인후 올바른 정보이면 토큰(키-값) 형태로 보내준다. 이를 테면 access - adib2.kos.2AidC0l 이 형태는 인코딩된 문자열 3개를 이어붙인 형태이며 실제론 몇 백 글자 이다.
Authorization은 HTTP 요청 헤더 중 하나로, 클라이언트가 서버에게 특정한 인증 정보를 제공하여 자신의 신원을 확인하고 보호된 리소스에 접근하려는 권한을 요청하는 데 사용된다. 이 헤더는 보통 토큰 기반의 인증 시스템에서 주로 사용된다.
JWT 구성
앞서 설명했든 토큰의 형태는 인코딩된 데이터 3개를 이어 붙인형태이다. 아주 짧게 adib2.kos.2AidC0l 이러한 형태인데,
순서대로 header, payload, verify Signature 로 구분된다.
{
"iss": "example.com", // 발급자 (Issuer)
"sub": "user123", // 주제 (Subject)
"exp": 1679768400, // 만료 시간 (Expiration Time)
"roles": ["user", "admin"] // 사용자 역할 등 (Custom Claim)
// ... 추가 클레임들
}
요약하면 토큰을 사용하게 되면 더이상 서버에 사용자의 정보를 저장하지 않아도 된다. 서버만이 갖는 비밀키와 요청에 있는 헤더와 페이로드 값을 통해 알고림즘 계산만 하면 인증이 가능하게 된다.
JWT 단점
토큰은 길이가 길어 요청이 많아지면 네트워크에 부하가 심해질 수 있다.
Payload 자체는 암호화가 되지 않아 중요한 정보는 담을 수 없다.
토큰을 탈취당한다면 대처가 매우 어렵다.
이러한 단점을 보완하기위해 access token, refresh token 등이 존재하며 이는 추후 다뤄 보도록 하겠다.