웹 서비스는 기본적으로 HTTP 통신 위에서 동작한다. 이 때 HTTP의 큰 특징 중 하나는 바로 stateless하다는 것이다. 간단히 말하면 서버가 클라이언트의 예전 상태를 보존하지 않는다는 뜻으로 비유하자면 클라이언트가 바로 직전에 한 말조차도 기억하지 못한다는 것! 예를 들면..

 

1번째 교신)

클라 : 제주도 가는 비행기 얼마에요?

서버 : 편도 7만원이요

 

2번째 교신)

클라 : 4장 주세요

서버 : ? 뭘요?

 

이런 느낌이다. 좀 더 자세한 얘기는 예전에 쓴 글 참조.

https://jofestudio.tistory.com/57

 

HTTP의 특징(stateless 등..)

1. 클라이언트 - 서버 구조 : HTTP는 클라이언트가 request를 보내면 서버가 response를 보내는 구조이다. 즉 클라이언트와 서버가 개념적으로 분리된 형태이며, 클라이언트로부터 request가 안오면 서버

jofestudio.tistory.com

 

 

암튼 이런 식으로 각 통신의 상태를 저장하지 않기 때문에, 인증 / 인가와 관련한 문제점이 생긴다. 로그인 이후 마이페이지같은 걸 요청할 때, 서버가 내 쪽의 상태를 모르니 매번 새 페이지를 요청할때마다 로그인을 해야 한다. 

 

이런 번거로움을 넘어서 비효율적인 일을 느낌있게 처리해야 한다. 기존에 이미 로그인한 사용자에 대한 정보를 저장해야 할 필요가 있는 것이다. 이를 위한 대표적인 방식들로 세션(Session)과 토큰(Token)을 기반으로 하는 인증방식들이 있다. 둘 다 유저가 로그인 시도 시 일치하는 유저 정보를 찾았다면 인증(Authentication) 완료의 표시로 일종의 확인증을 클라이언트에게 끊어주고, 클라이언트는 이후 로그인한 유저 정보가 필요한 곳에는 발급받은 확인증을 서버에게 건네어 인가(Authorization)를 받는다는 공통점이 있다. 그러나 둘은 차이점이 있고 서로간의 장단점이 있다. 이 둘에 대해 좀 더 뜯어보자.

 

 

세션 (Session)

일정 시간 동안 같은 사용자(정확히는 브라우저)로부터 들어오는 요구들을 하나의 상태로 보고 그 상태를 일정하게 유지시키는 기술을 말한다. 쉽게 말해 방문자가 웹서버에 접속해있는 상태를 하나의 단위로 보는 것. 컨셉은 다음과 같다.

 

  1. 유저가 로그인을 시도하면, 서버 쪽에서 DB를 뒤져서 일치하는 유저 정보를 찾는다.
  2. 찾았다면 그 클라이언트에 대한 세션id(일종의 확인증)을 발급해주고, 서버 쪽에서 갖는 세션 스토리지(Session Storage)에도 해당 정보를 저장한다. (세션id가 일종의 식별key)
  3. 클라이언트는 발급받은 세션id를 쿠키에 저장한다. (2번의 response로부터 set-cookie가 옴)
  4. 이후 클라이언트는 request를 보낼 때 쿠키를 헤더에 넣어 함께 전송(세션id가 들어있음)
  5. 서버는 클라이언트로부터 받은 세션id와 자신의 세션 스토리지에 있는 세션id를 대조해 인증 상태를 판단하고, 인가여부를 내린다.

 

서버 쪽에서 클라이언트의 세션정보를 본인의 메모리나 디스크..뭐 이런 곳에 저장하는 방식으로, 결국은 클라이언트의 상태를 계속해서 서버가 갖고 있고 이를 서비스에 이용하는 stateful방식이다.

 

※ 장점

서버가 클라이언트의 상태를 유지하고 있으니 로그인 여부 확인이 매우 용이하다. 맘만 먹으면 강제 로그아웃 등의 제재를 가하는 것도 쉽다. 

 

※ 단점

서버가 각 클라이언트들의 상태를 모두 갖고있는 셈이니, 당연히 메모리나 디스크 등에 부하가 걸리기 쉽다. 가장 치명적인 단점은 MSA(Micro Service Architecture)문제점이다.  사용자가 많아지면 서버를 여러 개로 늘려 확장한 다음, 로드밸런서(Load Balancer)를 둬서 각 클라이언트들의 보내는 request들을 처리할 서버를 이곳 저곳으로 전달해야 한다. 이 때 내가 로그인을 요청했던 서버와 이후 요청을 보낸 서버가 달라지면, 그 서버에는 내가 아까 로그인을 할 때 저장된 세션 정보가 없다는 문제가 발생하게 되는 것. 이렇게 되면 세션 정보가 없는 다른 서버에 접속할 때마다 계속 로그인을 해야 하는 참사가 생겨버린다. 이를 위해 각 서버들의 세션 스토리지를 동기화해주는 세션매니저(Session Manager)를 두는 방법 등이 있긴 하지만 추가적인 cost가 발생하게 된다..

 

 

토큰(Token)

세션 기반 인증 빙삭이 세션 정보(즉 인증 정보)를 서버에 저장하고 사용하는 식이라면, 토큰 기반 인증 방식은 서버가 아닌 클라이언트가 인증 정보를 직접 들고 있는 방식이다. 대표적으로 JWT(Json Web Token)방식이 가장 유명하다.

 

저작권 문제시 삭제하겠습니다..

 

컨셉은 다음과 같다

 

  1. 유저가 로그인을 시도하면, DB를 뒤져서 일치하는 유저 정보를 찾는다
  2. 찾았다면, 서버 쪽에서 가지고 있는 Secret key로 토큰을 발급한다.
  3. 클라이언트는 발급된 토큰을 저장하고, 이후 요청부터 토큰을 HTTP header에 실어 함께 보낸다.
  4. 서버는 단순히 전달받은 토큰이 유효한지 검증하고, 유효하면 인가해준다.

 

※ 장점

서버 쪽에서 저장하는 게 아니니 서버 쪽의 메모리가 확보된다. 또한 서버를 여러 개로 확장한 경우에도 모든 서버컴퓨터가 유저 정보를 기억하게 할 필요가 없다. 즉 확장성 쪽에서 엄청난 장점을 가진다. 

 

※ 단점

세션 인증 방식의 경우 세션 id만 실어서 보낸다. 반면 토큰의 경우는 사용자 인증 정보 뿐만 아니라 토큰의 발급 시각, 토큰의 id등의 정보도 가지고 있다. 즉 세션id보다 토큰의 사이즈가 더 크기 때문에 훨씬 더 많은 네트워크 트래픽이 유발된다.

뿐만 아니라 세션 인증 방식은 인증 정보를 서버에서 관리하는 반면 토큰은 클라이언트가 모든 인증 정보를 들고 있는 셈이라 보안 측면에서 좀 아쉽다. 세션id는 해커들에게 탈취돼도 서버측에서 해당 세션을 무효 처리하면 되는 반면 토큰은 해커들도 탈취한 다음 지들 맘대로 사용할 수 있다. 

+ Recent posts