둘 다 로그인이 되어있는지(권한이 있는지) 확인할 때 사용
세션은 사용자가 로그인을 하면 사용자 브라우저에게 세션 아이디를 발급하고 이를 쿠키로 저장
서버 또한 이 사용자 정보를 세션 아이디와 함께 메모리, 하드, 데이터베이스 등에 저장
권한이 필요한 요청을 하면 서버는 그 요청에 담긴 쿠키를 읽어 세션 아이디를 받아 그 세션 아이디로 서버에 저장되어있는 세션 아이디인지(로그인이 된 사용자인지) 확인하고 권한을 부여하거나 거부
이러한 세션 방식은 요청마다 세션 아이디를 저장해놓은 메모리나 하드, 데이터베이스 등을 조회해야 하므로 비용이 큼
JWT 방식은 이러한 단점을 보완하기 위하여 고안된 방식
JWT는 암호화된 3가지 데이터를 마침표(.)로 구분하여 이어붙인 모양을 함
암호화된 데이터를 Base64로 디코딩을 하면 JSON 형식의 정보를 얻을 수 있음
각각의 3가지 데이터는 처음부터 헤더(header), 페이로드(payload), 서명(verify signature)
만약 페이로드의 정보를 누군가 악용하여 바꿔놓는다면(예를 들어 관리자 여부를 true로 바꿔 악용) 위험함
→ 헤더와 서명의 정보로 방지, ‘서버에 감춰놓은 비밀 값’을 모르면 조작할 수 없음
서버는 요청에 토큰 값이 실려들어오면 헤더, 페이로드의 값을 ‘서버에 감춰놓은 비밀 값’과 함께 돌려봐서 계산된 결과값이 서명 값과 일치하는 결과가 나오는지 확인
만약 페이로드의 정보가 서버가 아닌 누군가에게 조금이라도 수정되었다면 맞지 않음
→ 조작한 사용자이거나 해커 등으로 간주하여 요청 거부
만약 서명 값과 일치하고, 토큰의 유효 기간도 지나지 않았다면 회원으로서 인가를 받은 것
이 방법으로 서버에 데이터를 저장해 요청마다 비교를 해줘야 하는 세션 방식과 달리 ‘비밀 값’을 통해 토큰을 스캔해서 인가를 진행
→ 시간에 따라 바뀌는 어떠한 상태값을 갖지 않는 stateless (세션은 stateful)
그러나 세션을 대체하기에는 JWT는 큰 결점이 있음
세션은 구현하기 부담스럽고 고려사항도 많지만 기억하는 대상의 상태들을 언제든 제어할 수 있다는 장점이 있음
예를 들어, 한 기기에서만 로그인이 가능한 서비스를 만드려는 경우 PC에서 로그인한 상태의 어떤 사용자가 핸드폰에서 또 로그인을 한다면 PC에서는 로그아웃 되도록 기존 세션을 없앨 수 있음
그러나 JWT에서는 불가능(이미 준 토큰을 회수할 수 없고, 토큰 발급 내역이나 정보를 서버에서 저장하지 않기 때문)
→ 통제가 세션에 비해 어려움
또한 토큰을 어떤 악성 사용자에게 뺏길 경우 토큰을 무효화 할 방법이 없음
토큰의 유효 시간을 아주 짧게 잡고, 유효 시간이 긴 리프레쉬 토큰을 함께 사용하여 토큰의 도난을 방지하는 방법도 있음
하지만 어쨌든 그 짧은 유효 시간 안에 악성 사용자가 무슨 일을 한다면 바로 차단할 방법은 없음
→ JWT의 한계, 그래서 JWT만으로 인가를 진행하는 서비스는 별로 없음
ㄱㅅ요