본문 바로가기

컴퓨터공학

세션 쿠키 그리고 JWT

많은 서비스에서 지원하는 로그인과 로그아웃.

흔히 볼 수 있는 서비스이기에, 만만해보이지만 사실 쉽지않다는 걸 알고있습니다.

이를 위한 내용들을 포스팅해보고자 합니다.

 

  먼저, 많이 들어본 Authentication 그리고 Authorization 한글로 하면 인증인가.

 

쉽게말하면 인증은 내가 내다 아이디와 패스워드를 통해 확인을 받는 것이고,

인가는 인증 '후' 인증받은 내용을 바탕으로 일련의 활동을 할 수 있는 이용권을 얻은 것. 조금 더 다듬어서 정리하자면, '로그인이 유지되는 상태에서 일어나는 일들' 이다.

 

그럼 이제 이 인증 후 서버가 알게 된 아이디와 패스워드를 항상 클라이언트와 서버가 주고 받는 것이냐?

그것은 아니다. 이는 잠깐 생각해도 보안상 취약점 있을 것이라고 알 수 있다. 중간에 스니핑이 없으리란 법이 없다.

 

그렇게 생각 된 방법은 서버 쪽에 저장하고 쿠키와 세션을 활용한 요청이 올 때 마다 대조해서 인가를 해주는 방식이다.

이는 어떻게 도입됐냐면, HTTP프로토콜은 Stateless방식 즉, 페이지와 페이지 간에 정보를 공유할 수 없는 방식이다. 그렇기에 세션 트래킹(서블릿 간 상태와 정보 공유)을 하는 '쿠키'가 도입되었는데, 쿠키는 서버가 정보를 저장해 브라우저에게 보내주고 받은 브라우저 즉 클라이언트가 이를 보관한다. 그리고 재접속 마다 브라우저가 서버에게 보낸다.

 

서버의 메모리 또는 데이터베이스 등에 사용자 정보를 저장해서 클라이언트가 요청오면 이를 비교해보고 인가를 결정한다.

하지만 이는 먼저 메모리에 저장한다면 휘발성이기에 서버가 재부팅해야할 상황이 온다면 불가피하게 모두 세션이 끊기는 상태가 발생할 것이고, 더욱이 수 만명의 사람이 접속을 하는 큰 서비스라면 속도나 용량 측면에서 불이익이 있을 것이다.

 

그렇기에 생각 해낸 방식 중 하나가 JWT 토큰을 이용하는 것이다. JWT토큰은 JSON Web Token의 줄임말이다. JWT토큰은 토큰만 줘버리고 서버는 앞선 케이스와 달리 잊는다. 그렇다면 서버가 모르는데 무슨 의미인가 할 수 있지만, JWT토큰을 자세히 들여다 보면 해법이 있다. JWT토큰은 세가지가 이어 붙여져 있는 토큰이다. Header Payload Verify Signature(서명값).

 

먼저 header를 디코딩해보면, type과 algoritm이 들어있다. type은 항상 jwt가 들어가고 alg는 뒤에 verify signature를 어떻게 암호화 할 것 인지 결정한다. sha456 등 활용 한 기억이난다.

 

payload는 base64로 디코딩해보면 토큰 정보가 들어있다 (토큰 발급자 유효기간 대상자 public으로 필요한 정보(닉네임)등.) 이러한 payload에 담긴 데이터들을 claim이라고 한다.

 

verify signature(서명값)는 암호화 알고리즘으로 만든 header+payload+서버가 갖고 있는 비밀값이다. 서버는 요청에 토큰이 들어오면 이 토큰과 비밀 값을 암호화 알고리즘에 넣고 서명값과 대조를 한다. claim이 조금이라도 변경되었다면 일치 하지 않을 것이고 임의로 맞추려해도 서버의 비밀값을 모르기에 무조건 틀렸다고 나올 것이다.

 

하지만 무결해보이는 이 JWT토큰도 단점이 있다. 바로 서버가 회원 상태를 모른다는 것이다. 서버가 모르게 되면 만약 다른 곳에서 해커와 주인이 접속을 해도 동시접속을 알수도 없고 그로인해 경고를 고지할 수도없게되고 외부로 유출된다면 파악할 수가 없는 등 여러 문제가 생긴다. 

 

이를 해결하기 위한 방법으로 Access Token과 Refresh Token이 있다. 수명이 짧은 Access Token과 비교적 수명이 긴 Refresh Token을 활용해, 엑세스 토큰이 만료되었다면 리프레스 토큰을 서버에 보내서 데이터베이스에 조회해보고 맞다면 엑세스 토큰을 다시 사용자에게 보낸다. refresh 토큰이 유효할 동안에는 access token을 계속 유지할 수있다. 이상함이 감지되면 refresh token을 서버에서 끊어버리면 된다. 허나 access token이 유효한 동안은 막을 수가 없다는 단점이 덧붙여진다.