Http환경에서의 서버 인증

johan1103·2022년 9월 15일

Statless한 Http환경에서 어떻게 로그인을 구현할 수 있을까?

우리가 보통 이용하는 홈페이지는 주로 Http통신을 통해서 정보를 제공하는 페이지입니다.

Http통신의 가장 큰 특징인 무상태성과 비연결성 덕분에 서버는 상태를 저장할 필요가 없게되고, 이는 서버의 부담 감소로 이어집니다. 그렇기 때문에 많은 사이트들이 Http 통신 방식을 사용하는 것이구요.

그런데 상태를 저장하지 않고, 통신이 끝나게 되면 전의 요청을 잊어버리는 http통신으로 어떻게 사용자에 맞춤형 정보를 제공해야하는 개인 계정과 관련된 정보 서비스들을 제공할 수 있는 것일까요? 이를 가능하게 하는 이론에 대해서 알아보겠습니다.

로그인의 조건

로그인은 인증(Authentication)의 한 방법이다. 서비스를 사용하는 사람이 본인이 맞는지 확인하는 것을 인증이라고 합니다. 로그인 상태를 유지한다는 것은 인증상태를 유지한다는 것입니다.

쿠키와 세션

이러한 문제를 해결하기 위해서 존재하는 대표적인 방식이 쿠키와 세션입니다.

쿠키와 세션을 이용한 인증flow는 다음과 같습니다.

이미지 출처 : ([https://hyuntaeknote.tistory.com/3])

  1. 클라이언트에서 웹 서버로 인증 정보 (아이디, 패스워드)를 Http헤더 혹은 바디에 넣어서 보낸다.
    (헤더나 바디에 넣어도, http통신 자체는 탈취당할 확률이 아주 높기 때문에 인증할 때 비밀번호와 같은 민감한 정보는 암호화를 하는 것을 강력 추천합니다.)
  2. 웹서버에서 DB에 접근해서 ID,PW가 정상적으로 확인이 되었다면, 내부에 회원 세션을 생성해서 회원의 정보들은 세션에 담고, 세션을 식별할 수 있는 Session Id를 쿠키에 담아서 Http 응답할 때 돌려준다.
  3. 클라이언트는 인증된 세션 ID를 쿠키를 통해서 받고 이를 클라이언트 웹 브라우저의 쿠키 저장소에 저장한다.
  4. 인증이 필요할 때마다 클라이언트는 세션 ID가 담긴 쿠키를 보낸다.
  5. 웹서버는 담겨있는 세션 ID를 통해서 특정한 유저를 인지하고 그에 요청에 맞는 서비스를 제공할 수 있다.

즉, 한번의 인증이 끝난 이후에는 세션의 ID를 통해서 서버가 특정한 사용자를 인식할 수 있는 흐름을 가집니다.

장점

이러한 방식의 장점은 쿠키만 사용하여 민감한 정보들을 주고받을 때와 다르게 쿠키 자체에는 세션ID만 포함되어 있기 때문에 쿠키 자체에는 유의미한 데이터가 들어가 있지 않다는 점입니다.

단점

그러나 정보를 탈취하게 되면 당연하게도 쿠키또한 탈취할 수 있기 때문에 원래의 사용자 A가 아닌, 탈취한 사용자 B가 A인 척 서버에 정보를 요구하면 서버는 확인된 유저 A의 세션 ID 때문에 B유저를 A유저로 오인할 수 밖에 없습니다. 그렇게 되면 B유저가 A유저의 세션에 있는 정보를 탈취할 수 있습니다. 이러한 공격을 세션 하이제킹 공격이라고 합니다.

또한 세션의 정보를 따로 서버에서 저장해야 하기 때문에 서버의 저장 공간이 요구되고 자연스럽게 서버의 부하도 높아질 수 밖에 없을 것입니다.

Token 인증

토큰 기반 인증 시스템은 세션 쿠키 방식과 동일하게 클라이언트가 서버에게 인증을 성공한 순간 인증을 할 수 있는 객체를 http 헤더에 담아서 인증을 하는 방식을 사용합니다.

다만, 세션 쿠키 방식과 다르게 세션ID, 혹은 민감한 정보가 아닌, 토큰을 헤더에 담아서 인증한다는 특징이 있습니다.

클라이언트는 서버에게 요청을 할 때 요청 헤더에 토큰을 담아서 보내고, 서버는 서버가 제공한 토큰과의 일치 여부를 체크해서 인증 과정을 처리하게 됩니다.

장점

기존의 세션기반 인증은 서버가 메모리나 데이터베이스에 세션을 저장해 놓아야 하는 구조이기 때문에, 메모리 관리 측면을 서버에게 주기 때문에 동시 접속자가 많아질 수록 서버에게 부담이 가중되는 단점이 있었습니다.

반면 토큰 인증 방식은 정보들이 클라이언트에게 암호화되어서 저장되기 때문에 서버의 부담을 줄일 수 있습니다.

단점

하지만 기본적으로 암호화등을 하고 인증하기 위한 모든 데이터들이 들어가 있기 때문에 인증 요청이 많아질 수록 네트워크 부하가 심해질 수 있습니다.

또한 암호화 되지 않는 부분 (payload)가 있기 때문에 아주 중요한 정보는 담을 수 없습니다.

토큰은 탈취당하면 토큰 자체만으로 인증이 가능하기 때문에 서버에서 탈취당했다는 사실을 알기 힘듭니다. (이를 대처하는 방식으로 토큰 유효기간을 설정하고, 유효기간 또한 길지 않게 설정하는 방식이 있습니다.)

❗토큰은 앱과 서버가 통신 및 인증을 할 때 가장 많이 사용됩니다. (앱에는 쿠키와 세션이 존재하지 않기 때문입니다.)

토큰을 이용한 인증의 flow는 다음과 같습니다.

이미지 출처 : ([https://tansfil.tistory.com/58])

위의 그림은 대표적인 토큰의 한 종류로 JWT 토큰의 인증 과정을 나타낸 그림입니다.
1. 클라이언트가 서버로부터 로그인 요청을 보낸다.
2. 로그인 정보가 정확히 올바르게 들어온것이 확인 되면 서버는 토큰을 생성하고, http 헤더에 담아서 응답한다.
3. 응답을 받은 클라이언트는 쿠키나 별도 메모리에 저장해놓고, 서버에 요청을 할 때마다 헤더에 담아서 보낸다.
4. 서버는 전달받은 토큰을 검증하는 과정을 거치고 응답한다.

참고 자료

0개의 댓글