ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [모의 면접 CS 스터디] 세션, 쿠키, jwt
    CS/네트워크 2024. 1. 22. 18:59

    쿠키(Cookie)

    쿠키란 무엇이고 왜 사용하는 것일까?

    브라우저와 서버 간 데이터 전송에 사용되는 HTTP는 이전 요청에 대한 정보를 저장해둘 수 없는 특징을 가지기 때문에 각 클라이언트를 식별하지 않는다. 하지만 현대 웹 어플리케이션에서는 여러 복잡한 기능을 구현하거나 편의성을 위해 서버에게 웹 브라우저를 개별적으로 식별할 수 있게 만들 필요가 있다. (그렇지 않으면 정말 끔직하게도 매번 사이트에서 페이지를 이동할 때마다 다시 로그인 해야 될 것이다. ) 

    따라서 서버는 웹브라우저에게 쿠키라는 것을 전달하여 매 요청마다 쿠키를 통해 브라우저에 대한 정보를 제공도록 만들어 이러한 문제를  해결할 수 있다. 즉 쿠키란 서버에서 클라이언트를 식별하는 데에 사용되는 정보를, key-value 형태로 브라우저에 저장한 것이라고 할 수 있다. 

     

    종류

     

    •  세션 쿠키(session cookie): 웹사이트에 방문하였을 때 일시적으로 생성되는 쿠키이다. 브라우저를 닫으면 삭제되며 로그인된 유저의 인증이나, 쇼핑 카트를 저장할 때 사용된다.
    • 영구 쿠키(persistent cookie): 사용자가 웹사이트에 처음 접속할 때 생성되며 특정한 만료 기간까지 계속 브라우저에 저장되는 쿠키이다. 일반적으로 유저의 언어 설정이나 유저의 웹사이트 활동을 추적하여 맞춤 광고를 제공하는 데에 사용된다.

     

    세션(Session)

     

    쿠키를 통한 유저 인증 시 문제점

     

    웹사이트는 쿠키를 이용해서 어떻게 로그인된 유저를 식별할 수 있을까? 가장 간단하게 생각할 수 있는 건 쿠키 자체에 아이디, 패스워드를 저장하는 것이다. 하지만 쿠키는 웹브라우저에 보관되어있기 때문에 유저가 쉽게 해당 정보를 수정할 수 있고 XSS나 CSRF 공격등으로 해커에게 손쉽게 탈취될 수 있다. 이러한 쿠키의 보안 문제 때문에 서버 측에서 사용자에 대한 인증 정보를 저장하는데 이게 바로 세션 ID라는 것이고 이러한 인증방식을 세션 기반 인증방식이라고 한다. 

     

    세션의 개념적 정의?

     

    In the context of web development, a session refers to a way of maintaining state information about a user’s interactions with a website or web application. When a user visits a website, the server can create a session for that user. Additionally, a session allows the server to keep track of information such as the user’s login status, preferences, and any data entered into forms. 

    (웹 개발의 관점에서 세션이란 유저와 웹 사이트 간의 상호 작용에 대해 상태 정보를 관리하는 수단을 의미한다. 유저가 웹사이트를 방문할 때 서버는 그 유저에 대한 세션을 만들 수 있다. 또한 세션을 통해 서버는 사용자의 로그인 상태, 기본 설정, 폼에 입력된 모든 데이터 등의 정보를 추적할 수 있다.)

     

    A web session is a period of interaction between a user and a website. Furthermore, the website maintains state information about the user’s actions and preferences during a session. The server can initiate a session for a user when they browse through a website. The session remains active until the user logs out.

    (웹 세션이란 사용자와 웹사이트 간의 상호 작용하는 기간이다. 또한 웹사이트는 세션 동안 사용자의 행동과 기본 설정에 대한 상태 정보를 유지한다. 서버는 사용자가 웹사이트를 브라우징할 때 해당 사용에대한  세션을 시작할 수 있다. 세션은 사용자가 로그아웃할 때까지 활성 상태로 유지된다.)

     

    여러 정보를 찾다 보니 세션이라는 용어가 다양한 의미로 사용되는 것 같아서 개념적 정의 비슷한 걸 찾아보았다. 쿠키와 세션을 한 묶음으로 사용할 때의 세션은 서버 측에 저장된 유저의 정보를 의미하는듯 하고, 혹은  유저와 웹 사이트 간의 상호 작용이 이루어지는 기간이라고 할 수 있을듯 싶다.

     

    동작 과정

     

    1) 웹 브라우저가 ID와 패스워드를 보내어 서버로부터 인증을 받는다.(HTTPS로 이루어진다면 탈취당할 걱정은 덜 수 있을 것이다.)

     

    2) 서버는 인증된 사용자임을 확인하고 고유성과 무작위성을 가진 세션 ID를 생성한 뒤 해당 유저에 대한 정보와 함께 세션 저장소(DB, 파일 시스템 등)에 저장하고, 또한 response 메세지의 Set-Cookie 헤더에 세션 ID를 두어 브라우저에게 전달한다.

     

    3) 브라우저는 매 요청마다 세션 ID가 저장된 쿠키를 헤더에 담아 보내고 서버 측에서 세션 저장소를 확인하여 해당 세션 ID가 있다면 가능한 리소스에 대한 인가를 받는다.

     

    4) 세션 쿠키에 세션 id가 저장되어 있으면 브라우저가 닫히는 순간 해당 쿠키는 폐기되고, 영구 쿠키에 저장되어있을 경우 만료 기간 동안까지만 저장된다.서버 측의 세션 ID는 만료기간까지 재사용되고 혹은 유저가 다시 로그인할 경우 다시 생성한다.

     

    이점

     

    위 동작 과정을 살펴보면 브라우저의 쿠키에도 세션 ID가 저장된다는 것을 알 수 있을텐데, 이는 여전히 인증에 필요한 정보가 해커에게 털릴 가능성이 높다는 것을 의미한다. HttpOnly나 Secure 등의 설정을 통해 이를 방지할 수 있긴 하지만 세션 하이재킹 등 여전히 탈취 가능성은 존재한다. 그렇다면 어떤 이점 때문에 세션 기반 인증 방식을 사용하는 것일까?

     

    세션 ID는 무작위적으로 생성 가능하기에 설령 해커에게 탈취 당한다고 하더라도 폐기하여 다시 만들 수 있기 때문이다. 다만 해커 측에서 세션 저장소 등을 공격하여 정보를 탈취했으면 모를까 클라이언트 측에서 세션 ID를 탈취당했는지 서버에서 감지하는 것은 쉽지 않을 것이다. 따라서 이를 위한 수단을 마련하고 세션 ID의 만료 기간을 적절하게 설정하는 것이 중요할듯 싶다.  

     

     

    문제점

     

    세션 기반 인증의 문제점은 유저의 세션 ID를 서버 측에서 저장해야 한다는 데에 있다. 로그인 유저의 수가 많아지면 세션 ID를 매 요청마다 확인하기 때문에  I/O 요청이 빈번히 발생하여 서버 측의 데이터 리소스 사용량이 높아진다는 문제가 있다. 또한 늘어난 트래픽에 대응하여 서버 인스턴스를 늘린다고 하였을 때 각 인스턴스 간의 세션 ID를 동기화 시키는 데에 비용이 든다.(이에 대한 자세한 내용은 이 글을 참고)  이러한 문제를 해결하기 위해 등장한 것이 토큰 기반 인증 방식이며 현재 웹개발에서 자주 사용되는 토큰이 바로 JWT이다.

     

    JWT 

     

    토큰 기반 인증 방식은 세션 인증 방식에 비해 어떤 이점이 있나?

     

    토큰 인증 방식은 세션 인증 방식과 다르게 사용자의 인증 정보를 서버가 관리하지 않고 브라우저가 관리한다. 따라서 사용자가 늘어나도 세션을 관리할 필요가 없기 때문에 서비스의 부담이 줄어들고 세션 동기화 때문에 골머리를 앓을 필요가 없다.

     

    그런데 쿠키의 사례를 보면 인증 정보를 클라이언트가 온전히 클라이언트가 관리하는 건 위험한 거 아닌가하는 의문이 든다. 물론 세션을 통해 관리하는 것보단 다소 취약할 수 있지만 JWT의 특징을 살펴보면 그 이점을 알 수 있다.

     

    JWT의 발급과정에서 서버는 사용자가 로그인을 통해 인증을 완료하면 JWT header, payload, signature 세 부분으로 나누어진 JWT 토큰을 발행한다. signature가 바로 JWT 보안의 핵심이다. signature는 비대칭키 방식을 사용하여 서버가 자신이 가진 비밀키를 이용해서 header와 payload를 합쳐서 만든 것이다. 서버는 추후 보낸 사용자의 토큰의 header와 payload를 비밀키로 암호화하여 signature로 다시 만들고 토큰의 signature와 비교하여 위조 여부를 판별하고 맞으면 사용자에게 데이터에 대한 접근 권한을 인가해준다.

     

    여기서 약간 의아할만한 부분은 signature를 마음껏 복호화 가능한데 보안성 있는 인증을 가능하게 하냐는 점인데 이 signature를 암호화 할 수 있는 키가 서버가 가진 비밀키뿐이기 때문이다. 만약 다른 사람이 관리자 권한에 접근하기 위해서 payload를 수정하더라도 이를 다시 암호화 하려면 서버의 비밀키가 필요하기 때문에 비밀키를 알지 못하면 JWT 토큰을 변조하는 건 불가능하다.

     

    확장성 측면에서의 이점

     

    그리고 여기서 생각할 수 있는 또 하나의 장점은 비밀키를 이용해서 유효성을 판별할 필요 없이 공개키로도 충분히 토큰의 유효성을 알 수 있다는 것이다. 왜냐하면 비대칭키의 특성상 signature를 공개키로 해독하고 header와 payload와 비교해서 유효성을 검증할 수 있기 때문이다. 따라서 다른 서비스에서도 서버가 발급한 공개키를 이용해 유효성을 검증할 수 있기 때문에 보다 어플리케이션의 확장성을 높일 수 있다.

     

    예를 들어 소셜 로그인 서비스 A가 인증 주체이고 이때 다른 서비스 B는 사용자의 인증을 A를 통해 한다고 가정하자.이 때 세션 방식을 사용한다면 사용자의 유효성을 검증하기 위해 B는 매번 서비스 A에게 인증을 요청해야 하고 이는 B 입장에서도 A 입장에서도 좋지 않을 것이다.

     

    먼저 A는 자신의 서비스를 운용하는 데에도 세션을 사용할텐데 여기에 다른 서비스의 인증을 위해서 세션 DB에 접근 하면 엄청난 부하가 걸릴 것이기 때문이다. 이는 소셜 로그인 서비스를 이용하는 서비스가 많아질수록 더욱 더 심해질 것이다. 

    한편 B 입장에서는 A에게 인증을 의존하고 있기 때문에 만약 A에 문제가 생기면 B 또한 정상적인 서비스를 할 수 없게 될 것이다. 

     

    하지만 토큰 방식을 사용한다면 이야기는 달라진다. A는 그저 사용자에게 토큰을 발급하면 되고 사용자는 B에 접근할 때마다 A에서 발급해준 토큰을 사용하면 된다. B는 A에 요청할 필요없이 그냥 공개키를 이용해서 토큰을 검증하면 된다. 

     

    토큰 인증 방식의 문제점 

     

    JWT 토큰은 세션 ID에 비해 많은 내용을 담고 있기 때문에 오버헤드가 크다. 그리고 세션 ID와 마찬가지로 해커가 사용자의 토큰이 탈취하면 해당 사용자인 척 위장할 수 있다는 문제점은 동일하다.

     

    따라서 서버 측에서는 Access token(인증시 사용하는 토큰)의 발급과 더불어 Refresh token을 클라이언트에게 발급해주는데,  토큰의 만료기간이 지나면 클라이언트 측이 보낸 Refresh token의 유효성을 검증한 뒤 새로운 Access token을 발급한다. 문제는 Refresh token까지 탈취 당하면 답이 없다는 거다. 보통 Access Token이 자주 탈취 당하기 때문에 만료 기간을 짧게 잡고 Refresh token은 길게 잡는데 이 때 서버 입장에선 매우 오랫동안 해커가 마음껏 로그인 하는 걸 막을 수 없다.

     

    따라서 Refresh token을 DB에 저장하고 이에 더해 사용자가 로그아웃 하면 Access token을 만료시키는 등의 방법으로 이 를 막아야하는데 이러면 결국 사용자가 어떤 Access token을 들고 있는지 식별해야 하기 때문에 세션 인증 방식과 비슷하게 stateful한 방식이 되어버린다. 

     

    하지만 그럼에도 위에서 말했듯이 JWT만으로도 인증이 가능하다는 특성 덕에 확장성이 좋기 때문에 여러 서비스가 분산된 마이크로 서비스 아키텍쳐에선 좋다고 한다. 

     

     

     

     

     

    참고자료

    세션 기반 인증과 토큰 기반 인증 (feat. 인증과 인가)

    쿠키와 세션 (ft. HTTP의 비연결성과 비상태성)

    What Are Sessions? How Do They Work? | Baeldung on Computer Science

    JWT(Json Web Token) 알아가기

    JWT (Json Web Token)와 비대칭키

     

    댓글

Designed by Tistory.