개발자 블로그

세션과 토큰 본문

CS/Network

세션과 토큰

hayongwoon 2022. 6. 20. 11:55

 프로젝트를 하면서 인증 방식을 어떻게 구현할지는 개발자의 선택이고 때문에 보편적으로 사용되고 있는 몇가지 방식의 장단점을 잘 알고 상황에 맞춰 프로젝트에 적용시킬 수 있어야 한다.

 

 일단 우리는 왜 인증 절차를 취할까? http의 특징을 짚고 넘어가면 http는 무상태성을 유지한다. 무상태성(stateless)는 사용자의 상태를 알고 있지 않다는 것이다. 서비스가 점점 복잡해지면서 서버는 사용자의 상태를 파악하고 이에 맞게 응답을 해줄 필요가 있다.

 따라서 http의 무상태성을 보완하기 위해 몇가지 인증 방식이 있다. 가장 보편적으로 사용되고 있는 세션 토큰 방식JWT토큰 방식을 위주로 설명해보자!

 

인증과 인가

  • 인증은 로그인을 하여 유저가 해당 서비스의 사용자라는 절차를 밟는 것이 인증!
  • 인가는 permission을 생각해보면 사용자 별로 해당 서비스에서 사용할 수 있는 기능들을 나누었는데, 이 때 사용자가 인증을 통해 구분 된 기능들을 사용하게끔 하는 것이 인가이다. 

 

세션 토큰 방식(stateful)

 세션 토큰 방식은 처음 로그인에 성공한 사용자에게 sessionID를 토큰이라는 곳에 부여하고 서버에서도 발급한 sessionID를 따로 디비(세션디비)에 저장해두었다가 해당 유저의 다른 요청이 왔을 때, 유저가 갖고 있는 세션아이디와 세션디비에 있는 아이디와 같은지 확인하며 로그인 된 상태를 유지하는 방식을 세션이라고 한다.

 

 오! 그러면 사용자가 엄~청나게 많은 서버라면 세션디비의 부하가 생기진 않을까 그리고 여러 개의 서버로 구성된 서비스가 있을 수 있는데 각각의 서버에는 유저의 세션아이디가 없을 것인데, 하는 의문점이 들 수 있다. 이러한 부분을 보완하기 위해서 레디스와 같은 메모리형 디비서버를 구축하여 공용의 서버로 두어 이러한 부분을 보완할 수 있다. 하지만 이러한 작업들이 단순하지만은 않다. 이러한 것을 간소화하기 위해 나온것이 바로 JWT 토큰 방식이다.

 

JWT 토큰 방식(stateless)

 json web token - 인코딩 또는 암호화 된 3가지 데이터를 갖고 있는 토큰을 발급한다. 그리고 해당 토큰에 대한 정보는 서버에서는 따로 관리 하지 않는 방식이다. json으로 암호화된 토큰만을 갖고 인증을 하는 방식이 되겠다. 

 3가지 데이터의 구조는 header, payload, verify signature이다. 각각의 데이터가 갖고 있는 것들을 확인하고 어떻게 인증이 되는지 알아보자. 

 

가운데인 payload는 Base64로 디코딩해보면 JSON형식으로 여러 정보들이 있다. 이 토큰을 누가 누구에게 발급했는지, 이 토큰이 언제까지 유효한지 그리고 서비스가 사용자에게 이 토큰을 통해 공개하기 원하는 내용이 무엇인지('클레임' - 사용자의 닉네임, 서비스상의 레벨, 관리자 여부 등) 서비스 측에서 원하는대로 담을 수 있다. 따라서 이 부분이 토큰에서 가장 중요한 정보가 담긴 부분이다. 

 

 그러면 이부분을 누군가 탈취해서 조작하여 Base64로 디코딩한 다음 조작할 수 있지 않나라는 생각을 할 수 있다. 그래서 1번과 3번 부분에서 이를 탈취 못하도록 되어있다. 

 

1번 header는 type과 alg가 들어간다. type은 이 형식이 json이니까 항상 json이라는 값이 명시 되어있고, alg는 알고리즘의 약자로 3번 서명 값을 만드는데 사용될 정보이다. HS256등 여러 암호화 방식이 있는데, 그 중 하나를 지정할 수 있다.

그렇게 나온 알고리즘을 통해 1번 헤더, 2번 페이로드 그리고 '서버에 감춰놓은 비밀 값'을 해당 암호화 알고리즘에 넣으면 3번 서명 값이 나오는 것이다. 

 이러한 방식으로 아무리 2번 값에 대한 내용을 탈취를 해도 3번 정보가 맞을 수가 없기에 보완의 신뢰성을 높인 것이라 할 수 있다.

 

stateful vs stateless 

 사용자의 상태를 기억하고 있는 세션 토큰 방식의 경우 사용자의 상태를 디비를 통해 기억하고 있기 때문에 언제든 제어가 가능하다. 예를 들어 노트북이나 핸드폰 다른기기에서 같은 사용자가 접속할 경우 PC에서는 로그아웃 되거나 하도록 기존 세션을 종료할 수 있다. 

 

 그래서 stateless한 JWT토큰 방식의 경우 이러한 부분과 누군가 토큰을 탈취하는 것을 보완하기 위해 access Token, refresh Token을 사용하는 방법도 있다. 

 

 accessToken은 만료기간이 짧은 토큰이고, refresh Token은 상대적으로 긴 토큰이다. 이 두가지 토큰을 사용자에게 주고 리프레시 토큰의 상응값을 디비에 따로 저장해둔다. 그래서 어세스 토큰의 유효기간이 다 되면 디비에서 리프레시 토큰을 확인하여 새 어세스 토큰을 발급해주어 이러한 부분에 보완을 하기도 한다. 하지만 그렇다고 이 방법이 완전히 JWT의 단점을 보완했다고 보기는 어렵다. 

 

 따라서 아주 합리적이고 경제적인 방법이 될 수는 있지만, 이러한 점들을 고려하여 해당 문제가 크게 문제될 게 아니라면 고려해보는 것도 좋은 방식이겠다. 

 

 

'CS > Network' 카테고리의 다른 글

GET method의 특징  (0) 2022.08.09
Http와 연계하는 웹서버  (0) 2022.06.13
TCP/IP  (0) 2022.06.08