세션 기반의 인증과, 토큰 기반의 인증 방법
1. 인증, 인가 란?
웹 서비스를 개발하다보면 사용자 인증과 권한 처리 로직에 대한 고민을 하게됩니다.
사용자 인증(Authentication)은 사용자가 자신이 주장하는 신원을 증명하는 과정이며,
권한 처리(Authorization)는 인증된 사용자에 대해 허용된 작업 및 기능에 대한 권한을 부여하는 과정으로 인가 라고도 표현합니다.
인증은 식별 가능한 정보를 이용하여 서비스에 등록된 유저인지를 파악하기 위한 과정으로 일반적으로 사용자 이름과 비밀번호를 입력하여 이루어집니다.
인증 후에는 권한 부여가 이루어져야 합니다. 인증된 사용자가 접근하려는 자원에 대한 권한이 있는지 확인하는 과정으로 권한은 일반적으로 역할(Role)이나 권한(Permission)의 형태로 정의됩니다.
역할은 특정 그룹의 사용자들이 공통으로 가지는 권한을 묶어놓은 것입니다.
예를 들어, "관리자"라는 역할은 시스템 전체를 관리할 수 있는 권한을 가지고 있습니다.
권한은 각각의 사용자에 대해 개별적으로 설정할 수도 있습니다. 이 경우에는 사용자 식별자(ID)와 권한 사이의 연결을 데이터베이스나 파일 등의 저장소에 저장합니다.
보통은 인증과 권한 처리가 별도의 모듈로 분리되어 있으며, 각각의 기능을 수행하는 서버나 미들웨어에 연결됩니다. 이렇게 분리된 인증과 권한 처리 모듈은 다른 시스템에서도 재사용이 가능하며, 보안과 유지보수에도 이점을 제공합니다.
1.1 인증과 인가의 차이
인증은 식별 가능한 정보를 바탕으로 사용자가 해당 서비스를 이용할 수 있는지를 판단하는 과정이고, 인가는 인증된 사용자가 접근하려는 리소스에 대한 권한이 있는지 판단하는 과정을 말합니다.
2. 인증 방식
인증 방식에는 크게 세션 기반 인증 방식, 토큰 기반 인증 방식이 있습니다. 각 방법들은 장단점이 있으며, 사용자 인증 정보의 보안성, 유지보수성 등을 고려하여 적절한 방법을 선택해야 합니다.
2.1 URL 매개변수(Parameter) 기반 인증 방식
URL 매개변수는 URL 주소 뒤에 ?와 함께 전달되는 값으로, 페이지 이동시에 사용자 인증 정보를 URL 매개변수로 전달할 수도 있습니다. 하지만 보안상의 이유로 권장되지 않습니다.
2.2 HTTP 요청 헤더(Header) 기반 인증 방식
HTTP 요청 헤더는 클라이언트에서 서버로 보내는 요청에 대한 정보를 담고 있습니다. 사용자 인증 정보도 HTTP 요청 헤더에 담아서 서버로 전송할 수 있습니다. 예를 들어, JWT(Json Web Token)라는 인증 방식에서는 JWT를 HTTP 요청 헤더에 담아서 서버로 전송합니다.
HTTP는 무상태성(Stateless) 프로토콜로 누가 요청을 했는지, 인증된 클라이언트 인지 확인할 수 없다. 그래서 나온 방법이 서버측에 클라이언트의 접속 상태를 저장하는 세션 기반의 인증이다.
2.3 세션(Session) 기반 인증 방식
웹 애플리케이션에서는 사용자 인증에 세션을 이용하는 경우가 많습니다.
세션 기반 인증 방식의 핵심은 사용자의 정보를 세션 스토리지에 저장해 서버에서 관리 한다는것 입니다.
세션은 서버 측에 데이터를 저장하며, 사용자 인증에 대한 정보도 세션에 저장됩니다. 사용자가 로그인을 하면 세션에 사용자 정보를 저장하고, 페이지 이동시에도 해당 세션에서 사용자 인증 정보를 가져와서 사용합니다.
세션(Session) 이란?
세션이란 일정 시간 동안 같은 사용자(브라우저)로 부터 들어오는 일련의 요청을 하나의 상태로 보고 그 상태를 일정하게 유지시키는 기술을 말한다. 또한, 여기서 일정 시간이란 방문자가 웹브라우저를 통해 웹 서버에 접속한 시점으로 부터 웹 브라우저를 종료함으로써 연결을 끝내는 시점을 말한다. 즉, 방문자가 웹서버에 접속해 있는 상태를 하나의 단위로 보고 세션이라고 칭한다.
쿠키(Cookie) 란?
특정 웹 사이트를 방문했을 때 만들어지는 정보를 담는 파일을 말하며 쉽게 말해 상태 정보를 유지하는 기술 입니다.
쿠키는 브라우저 측에 데이터를 저장하며, 사용자 인증 정보도 쿠키에 저장될 수 있습니다. 사용자가 로그인을 하면 서버에서 쿠키를 생성하여 브라우저에 전송합니다. 이후에 페이지 이동시에도 해당 쿠키에서 사용자 인증 정보를 가져와서 사용합니다.
동작 방식
사용자 로그인
사용자가 로그인을 하면, 웹 서버는 사용자의 아이디와 비밀번호를 검증합니다. 검증에 성공하면, 서버는 세션 ID(Session ID)를 생성합니다. 이 세션 ID는 사용자를 구별하는 고유한 식별자로, 서버는 이 세션 ID를 이용하여 사용자의 상태를 추적합니다.
세션 정보 저장
세션 ID가 생성된 이후, 서버는 세션에 사용자 정보를 저장합니다. 이 사용자 정보는 사용자 인증 정보뿐만 아니라, 사용자가 서버에 요청을 보낼 때마다 필요한 정보를 저장할 수도 있습니다.
세션 ID 전송
로그인 후 서버는 생성한 세션 ID를 사용자에게 전송합니다. 이 세션 ID는 일반적으로 쿠키(Cookie)나 HTTP 응답 헤더(Response Header)에 담아서 전송됩니다.
세션 ID 유지
사용자가 페이지를 이동하거나 다른 요청을 보낼 때, 브라우저는 세션 ID를 포함한 요청을 서버에 전송합니다. 서버는 이 세션 ID를 이용하여 세션 정보를 찾아서 사용자 상태를 유지합니다.
세션 만료
일반적으로 세션은 일정 시간이 지나면 자동으로 만료됩니다. 만료된 세션은 서버에서 삭제되며, 다시 사용하려면 로그인 과정을 거쳐야 합니다.
세션 기반 인증 방식은 간단하고 유연한 방법으로, 대부분의 웹 애플리케이션에서 사용됩니다. 하지만 보안상의 이유로, 세션 ID가 노출되는 것을 방지하기 위해 HTTPS와 같은 보안 프로토콜을 사용하거나, 세션 ID를 안전하게 전송하는 방법을 사용해야 합니다. 또한, 서버에서 세션 정보를 안전하게 관리하고, 세션 만료 시간을 적절하게 설정해야 합니다.
세션 정보를 안전하게 전송하는 방법
HTTPS 프로토콜 사용
HTTPS 프로토콜을 사용하면, 세션 ID를 포함한 모든 요청과 응답이 암호화되어 전송됩니다. 이를 통해 중간자 공격(MITM Attack) 등의 공격으로부터 세션 정보를 안전하게 보호할 수 있습니다.
쿠키 속성 설정
쿠키(Cookie)는 일반적으로 세션 ID를 저장하는 용도로 사용됩니다. 이때, 쿠키 속성을 설정하여 세션 ID를 안전하게 전송할 수 있습니다. 예를 들어, Secure 속성을 설정하면 HTTPS 프로토콜을 사용하는 경우에만 쿠키가 전송되도록 설정할 수 있으며, HttpOnly 속성을 설정하면 JavaScript를 통한 접근을 막아 XSS 공격 등으로부터 보호할 수 있습니다.
토큰 기반 인증 사용
토큰(Token) 기반 인증 방식을 사용하면, 세션 ID 대신에 토큰을 사용하여 인증을 처리합니다. 이 토큰은 암호화되어 있으며, 서버와 클라이언트 간에 안전하게 전송될 수 있습니다. 이 방식은 API 서버와 같은 경우에 많이 사용됩니다.
보안 소켓 계층(SSL)을 이용한 VPN 연결
VPN(Virtual Private Network)을 이용하여 안전한 터널을 만들어서 세션 정보를 전송할 수 있습니다. VPN을 이용한 세션 정보 전송은 일반적으로 원격 접속 등에서 사용됩니다.
장점
1. 보안성이 높음 : 세션 ID는 서버 측에서 생성하고 관리하기 때문에, 사용자가 직접 세션 ID를 알 수 없어 보안성이 높습니다. 또한 HTTPS 프로토콜을 사용하면 세션 정보가 암호화되어 전송되기 때문에 중간자 공격(MITM Attack) 등의 공격으로부터 보호됩니다.
2. 다양한 인증 수단 활용 가능 : 로그인 정보, 쿠키, 토큰 등 다양한 인증 수단을 사용할 수 있어서, 보다 다양한 인증 방식을 적용할 수 있습니다.
3. 서버 측에서 세션 정보 관리 가능 : 서버 측에서 세션 정보를 관리하고, 세션에 대한 유효성 검사를 수행할 수 있습니다.
단점
1. 서버 부하 : 세션 기반 인증 방식은 서버 측에서 세션 정보를 관리해야 하기 때문에, 서버 부하가 증가할 수 있습니다.
2. 확장성 제한 : 세션 기반 인증 방식은 서버에서 세션 정보를 관리하기 때문에, 서버 확장성이 제한될 수 있습니다.
3. 세션 유지 시간 제한: 세션 기반 인증 방식에서는 일정 시간 동안 세션이 유지되며, 이 시간이 지나면 자동으로 로그아웃됩니다. 이로 인해 일시적으로 빈번한 로그인이 필요할 수 있습니다.
4. 보안 : 쿠키 노출은 문제가 없지만 해커가 HTTP요청을 가로챈다면 해당 쿠키로 서버에 부적절한 HTTP 요청을 보낼수 있다.
세션 기반 인증 방식은 보안성이 높은 인증 방식이지만, 서버 부하와 확장성 제한 등의 단점이 있습니다. 따라서, 사용 환경에 따라 적절한 인증 방식을 선택해야 합니다.
2.4 토큰 기반 인증 방식
토큰(Token) 기반 인증 방식은 세션(Session) 기반 인증 방식과 달리 서버가 클라이언트의 상태를 관리하지 않고, 세션 ID 대신 클라이언트가 서버로부터 발급받은 토큰(Token)이라는 문자열을 사용하여 인증을 수행하는 방식입니다. 때문에 사용자 인증시 서버에서 사용자 정보를 확인하지 않고 전달받은 토큰의 서명과 데이터를 검증하여 인증합니다.
토큰은 사용자가 로그인에 성공하면 서버 측에서 발급되며, 이 토큰은 클라이언트 측에서 저장합니다. 그리고 서버에서 요청에 대한 응답을 할 때마다, 클라이언트는 요청에 토큰을 함께 전송합니다. 서버는 이 토큰을 검증하여 인증을 수행합니다.
동작방식
1. 클라이언트가 로그인 요청을 보내면, 서버는 인증 정보를 검증하고, 클라이언트에게 인증이 성공했다는 응답을 보냅니다.
2. 서버는 클라이언트에게 토큰을 발급하고, 클라이언트는 이 토큰을 저장해둡니다. 대부분의 경우, 이 토큰은 HTTP 쿠키나 웹 스토리지에 저장됩니다.
3. 클라이언트가 다음 요청을 보낼 때마다, 토큰을 요청에 포함시켜 서버로 보냅니다.
4. 서버는 이 요청에 포함된 토큰을 검증하고, 클라이언트가 인증된 사용자인지 확인합니다. 만약 유효한 토큰이면, 서버는 요청을 처리하고 응답을 보냅니다.
장점
1. 서버 부하 감소 : 서버는 클라이언트의 상태를 관리하지 않기 때문에, 부하가 감소됩니다.
2. 확장성 향상 : 세션 기반 인증 방식과는 달리 서버에서 세션 정보를 관리하지 않고, 클라이언트가 토큰을 포함시켜 요청을 보내기 때문에, 서버의 확장성이 향상됩니다.
3. 다양한 플랫폼 지원 : 다양한 플랫폼에서 사용 가능하며, 모바일 애플리케이션과 웹 애플리케이션 모두에서 사용할 수 있습니다.
4. 다양한 인증 수단 활용 가능 : 로그인 정보, 쿠키 등 다양한 인증 수단을 사용할 수 있어서, 보다 다양한 인증 방식을 적용할 수 있습니다.
5. 안전한 인증 가능 : JWT(Json Web Token)와 같은 암호화된 토큰을 사용하면, 중간자 공격(MITM Attack) 등의 공격으로부터 보호됩니다.
6. 유연한 권한 관리 : 토큰에 사용자의 권한 정보를 포함시켜 사용자 인증과 권한 관리를 함께 수행할 수 있습니다.
단점
1. 보안성이 낮을 수 있음 : 클라이언트가 토큰을 저장하고 있기 때문에, 클라이언트에서 보안에 취약한 저장소에 저장될 경우 보안성이 낮아질 수 있습니다.
2. 토큰 유효기간 관리 : 토큰은 일정 시간 동안 유효하며, 이 기간이 지나면 토큰이 만료됩니다. 이를 관리하기 위해 토큰을 재발급하는 등의 추가적 작업이 필요합니다.
JWT(Json Web Token)
JWT(Json Web Token)는 토큰 기반 인증 방식에서 사용되는 표준으로, 속성 정보(Claim)를 JSON 데이터 구조로 표현한 웹 토큰으로 토큰 자체를 정보로 사용하는 Self-contained 방식으로 정보를 안전하게 전송할 수 있도록 지원합니다.
JWT는 상태를 저장하지 않기 때문에 한 번 만들어지면 토큰을 무력화하는 게 불가능합니다. 따라서 반드시 만료 기간을 설정해야 합니다. 또한, JWT 페이로드는 암호화되지 않기 때문에 중요 데이터를 넣지 않거나 암호화하는 방법을 사용해야 합니다. 마지막으로 페이로드에 속성 정보(클레임)을 저장하고 있기 때문에 정보가 많아질수록 토큰 길이가 길어집니다.
구조
JWT는 세 부분으로 구성됩니다.
Header : 토큰의 유형과 사용되는 알고리즘에 대한 정보를 담고 있습니다.
Payload : 토큰에 담을 정보, 즉 클레임(Claim)을 포함합니다. 클레임은 사용자 ID, 권한 등의 정보를 포함할 수 있으며, 클라이언트에서 서버로 전송할 정보를 담습니다.
Signature : Header와 Payload를 Base64Url로 인코딩한 문자열과 서버 측에서 가지고 있는 Secret Key를 이용하여 암호화한 값을 포함합니다.
장점
Stateless : JWT는 서버에서 세션 정보를 관리하지 않기 때문에 서버 확장성이 좋습니다.
안전한 전송 : JWT는 암호화된 문자열로 전송되기 때문에 중간자 공격(MITM Attack) 등의 공격으로부터 보호됩니다.
정보 전송 : JWT는 클라이언트에서 서버로 전송할 정보를 담기 때문에, 클라이언트와 서버 간의 데이터 전송에 사용될 수 있습니다.
단점
정보누출 : Payload를 인코딩하여 Base64Url로 전송하기 때문에, Payload를 암호화하여 전송하지 않는 한, Payload의 정보가 누출될 가능성이 있습니다.
전송 속도 : Payload의 정보가 많아지면, 토큰의 길이가 길어지기 때문에, 전송 속도가 느려질 수 있습니다.
JWT는 보안성이 높고, 서버 확장성이 좋으며, 클라이언트와 서버 간의 데이터 전송에 사용될 수 있는 장점이 있습니다. 하지만, Payload의 정보 누출 등의 단점도 존재하기 때문에, 적절한 상황에서 적용해야 합니다.
3. 세션 기반 인증과 토큰 기반 인증의 차이
세션 기반 인증과 토큰 기반 인증의 가장 큰 차이점은 사용자의 상태 정보를 저장하는 지입니다. 세션 기반 인증은 서버의 세션 스토리지에 사용자의 상태 정보를 저장하지만, 토큰 기반 인증은 사용자의 상태 정보를 저장하지 않고, 토큰이 유효한지만 판단합니다. 따라서 토큰 기반 인증의 경우 서버를 확장하기에 유연합니다.
또다른 차이점으로는 세션 기반 인증은 세션값 자체에 어떠한 정보를 저장하지 않지만 토큰 기반 인증은 토큰에 사용자 정보를 포합합니다. 따라서 토큰의 길이가 길어질 수 있고, 더 나아가 네트워크에 부하를 줄 수 있습니다.
4. 세션 기반 인증이 아닌 JWT 토큰 기반 인증 방식을 많이 사용하는 이유는 무었일까?
세션 기반 인증의 경우 서버의 세션 스토리지에 세션을 저장하고 있기 때문에 사용자가 급증하게 되면, 서버 부하가 심해질 수 있습니다. 하지만 토큰 기반 인증은 서버에 상태 정보를 저장하지 않고 토큰이 유효한지만 판단하기 때문에 사용자가 급증하더라도 서버 확장에 유연합니다.
Refresh 와 access 토큰의 차이점
액세스 토큰과 리프레시 토큰 모두 사용자 인증이 완료된 이후 서버에서 시크릿키를 사용하여 발급하는 토큰을 말합니다.
액세스 토큰은 사용자가 서버 리소스에 접근하기 위해 사용하는 토큰이고, 리프레쉬 토큰은 액세스 토큰이 만료되었을 때 재발급하기 위한 토큰입니다.
토큰은 서버에서 관리하지 않기 때문에 서버에서 임의로 무력화하기 힘듭니다. 따라서 액세스 토큰의 만료 기간을 짧게 두어 토큰이 탈취되더라도 금방 만료되어 안정성을 보장할 수 있습니다. 또한 액세스 토큰은 매 요청마다 메시지에 포함해 요청하는 반면, 리프레쉬 토큰은 액세스 토큰이 만료되었을 때만 메시지에 포함해 보내기 때문에 도난 가능성이 적습니다.
하지만 리프레쉬 토큰이 도난되면, 액세스 토큰을 지속적으로 발급할 수 있기 때문에 큰 문제가 발생합니다. 따라서 리프레쉬 토큰은 클라이언트가 아닌, 서버 사이드에 저장하는 방법을 통해 해당 문제를 해결할 수 있습니다.
연관된 글 :
참고 :
chatGPT
[JSP/세션관리] Cookie 쿠키 & Session 세션 이란 무엇인가? (개념, 용도)
[Server] JWT(Json Web Token)란?