JSON Web Token의 줄임말로, JSON 객체를 사용해 정보를 안정성 있게 전달하는 웹표준이다!
인증은 프론트엔드 관점에서 봤을 때 사용자의 로그인, 회원가입과 같이 사용자의 도입부분을 가리키곤 한다. 반면 서버사이드 관점에서 봤을 때는 모든 API 요청에 대해 사용자를 확인하는 작업이다.
token_receive = request.cookies.get('mytoken')
사용자 A와 사용자 B가 앱을 사용한다고 가정했을때, 두 사용자는 기본적으로 정보가 다르고 보유하고 있는 컨텐츠도 다를것이다. 따라서 서버에서는 A,B가 요청을 보냈을 때 누구의 요청인지를 정확히 알아야한다. 만일 그렇지 못한다면, 자신의 정보가 타인에게 유출되는 최악의 상황이 발생한다. 그렇기에 앱(프론트 엔드)에서는 자신이 누구인지를 알만한 단서 (토큰이 담긴 쿠키) 를 서버에 보내야 하며, 서버는 그 단서를 파악 (jwt를 이용한 디코딩) 해 각 요청에 맞는 데이터를 뿌려주게 된다.
현재 모바일이나 웹 서비스에서 가장 많이 쓰이는 통신 방식은 HTTP 통신입니다. HTTP 통신은 응답 후 연결이 끊기게 되면 과거에 대한 정보를 전혀 담지 않는다. 이 말은 지금 보낼 HTTP 요청은 지난 번에 내 정보를 담아 보냈던 HTTP 요청과 전혀 관계가 없다는 말이 된다. 따라서 각각의 HTTP 요청에는 주체가 누구인지에 대한 정보가 필수적이다(인증이 필요없다면 필요없을 수도 있음).
세션 쿠키 방식의 인증은 기본적으로 세션 저장소를 필요로 한다(Redis를 많이 사용). 세션 저장소는 로그인을 했을 때 사용자의 정보를 저장하고 열쇠가 되는 세션ID값을 만든다. 그리고 HTTP 헤더에 실어 사용자에게 돌려보낸다. 그러면 사용자는 쿠키로 보관하고 있다 인증이 필요한 요청에 쿠키(세션ID)를 넣어
보낸다. 웹 서버에서는 세션 저장소에서 쿠키(세션ID)를 받고 저장되어 있는 정보와 매칭시켜 인증을 완료한다.
세션은 서버에서 가지고 있는 정보이며 쿠키는 사용자에게 발급된 세션을 열기 위한 열쇠(SESSION ID)를 의미한다. 쿠키만으로 인증을 사용한다는 말은 서버의 자원은 사용하지 않는다는 것이며, 이는 즉 클라이언트가 인증 정보를 책임지게 되는것이다. 그렇게 되면 HTTP 요청을 탈취당할 경우 다 털리게 된다. 따라서 보안과는 상관없는 단순히 장바구니나 자동로그인 설정 같은 경우에는 유용하게 쓰인다.
결과적으로 인증의 책임을 서버가 지게하기 위해 세션을 사용하는 것이다.(사용자가 해킹당하는 것보단 서버가 해킹당하는게 훨씬 어려우니까!)
세션/쿠키 방식은 기본적으로 쿠키를 매개로 인증을 거친다. 따라서 쿠키가 담긴 HTTP 요청이 도중에 노출되더라도 쿠키 자체(세션 ID)는 유의미한 값을 갖고있지 않는다.(중요 정보는 서버 세션에 있으므로 세션 ID는 별 의미를 갖지 않음) 이는 꽤나 안전해 보인다.
사용자 A는 1번, 사용자 B는 2번 이런식으로 고유의 ID값을 발급받게 된다. 그렇게 되면 서버에서는 쿠키 값을 받았을 때 일일이 회원정보를 확인할 필요 없이 바로 어떤 회원인지를 확인할 수 있어 서버의 자원에 접근하기 용이할 것이다.
장점 1에서 쿠키를 탈취당하더라도 안전할 수 있다고 언급했지만 문제가 하나 있다. 만일 A 사용자의 HTTP 요청을 B 사용자(해커)가 가로챘다면 그 안에 들어있는 쿠키도 충분히 훔칠 수 있다. 그리고 B 사용자는 그 훔친 쿠키를 이용해 HTTP 요청을 보내면 서버의 세션저장소에서는 A 사용자로 오인해 정보를 잘못 뿌려주게 된다(세션 하이재킹 공격이라고 한다...!)
서버에서 세션 저장소를 사용한다고 했으므로 서버에서 추가적인 저장공간을 필요로 하게되고 자연스럽게 부하도 높아질 것이다.
세션/쿠키 방식과 가장 큰 차이점은 세션/쿠키는 세션 저장소에 유저의 정보를 넣는 반면, JWT는 토큰 안에 유저의 정보들을 넣는다는 점이다. 물론 클라이언트 입장에서는 HTTP 헤더에 세션ID나 토큰을 실어서 보내준다는 점에서는 동일하나, 서버 측에서는 인증을 위해 암호화를 하냐, 별도의 저장소를 이용하냐는 차이가 발생한다.
여기까지의 글만 봤을 때는 JWT가 세션/쿠키 방식보다 더 효율적으로 보인다. 하지만 JWT도 단점들이 존재한다.
이미 발급된 JWT에 대해서는 돌이킬 수 없다. 세션/쿠키의 경우 만일 쿠키가 악의적으로 이용된다면, 해당하는 세션을 지워버리면 된다. 하지만 JWT는 한 번 발급되면 유효기간이 완료될 때 까지는 계속 사용이 가능하다. 따라서 악의적인 사용자는 유효기간이 지나기 전까지 신나게 정보들을 털어갈 수 있다.
Payload 정보가 제한적이다. 위에서 언급했다시피 Payload는 따로 암호화되지 않기 때문에 디코딩하면 누구나 정보를 확인할 수 있다. (세션/쿠키 방식에서는 유저의 정보가 전부 서버의 저장소에 안전하게 보관된다.) 따라서 유저의 중요한 정보들은 Payload에 넣을 수 없다.
JWT의 길이다. 세션/쿠키 방식에 비해 JWT의 길이는 길다. 따라서 인증이 필요한 요청이 많아질 수록 서버의 자원낭비가 발생하게 된다.