JWT > 인가와 관련
세션
session id, 세션 아이디를 실어보내서 서버에서 매치되는 키 값과 비교해서 맞으면 세션 유지기간 동안 로그인 유지.
토큰
JWT jason web token 방식
서버가 기억하지 않고 토큰을 한 번 건내주고 끝
마침표를 기준으로 세 부분으로 나뉜다.
header, payload, verify signature 로 구분된다.
1) header, 헤더
토큰의 타입, JWT 고정이다.
alg, 서명값을 만드는데 사용될 알고리즘이 지정된다.
1번 헤더와 2번 페이로드, 그리고 서버에 "감춰놓은 비밀값(키)" 이 셋을 이 암호화 알고리즘에 넣고 돌리면 3번 서명값이 나온다.
이 암호화 알고리즘은 한 쪽 방향으로는 계산이 돼도, 반대쪽으로는 계산이 안되서 서버만 알고 있는 비밀 값을 찾아낼 방법이 없다.
그래서 토큰의 요청을 받을 때 마다 헤더, 페이로드, 그리고 비밀 키 값을 돌려서 서버 내부의 알고리즘 서명값과 토큰의 서명값을 비교해서 보안성을 체크한다.
사용자가 로그인을 하고 나서 서버에서 받는 토큰에 클레임이 담겨 오고,
이후에는 요청들마다 사용자에서 서버로 보내진다.
시간에 따라 바뀌는 어떤 상태값을 안 갖는걸 stateless 하다고 한다.
세션은 stateful 이다.
둘 다 장단점이 있다.
예를 들어 session의 경우 서버에서 가능만 하다면, session의 상테를 제어할 수 있다.
pc에서 로그인한 상태의 어떤 사용자가 핸드폰에서 또 로그인하면 pc에서는 로그아웃 되도록 기존 세션을 종료할 수 있다.
jwt 방식은 이런 구현이 어렵다. 이미 줘버린 토큰을 뺏을 수도 없고 그 토큰의 발급 내역이나 정보를 서버에서 저장해놓지도 않기 때문이다. 서버에서 쥐고 있을 필요가 없어서 편하지만, 그래서 통제는 못한다. 그리고 토큰을 탈취당할 경우 비교가 어렵기 때문에 실 서비스에서 jwt 만으로 구현하는 경우는 많지 않다.
이런 단점을 보안하기 위해 만료시간을 가깝게 잡아서 토큰의 수명을 아주 짧게 처리하는 방법이 있다. 그래서 로그인 유지를 위해 토큰을 두 개를 줘서, 수명이 몇 시간이나 몇 분 이하로 짧은 access 토큰과 꽤 길게, 보통 2주정도로 잡혀있는 refresh 토큰을 발급하고 나서 클라이언트에 보내고, refresh 토큰은 상응값을 데이터베이스에도 저장한다.
손님은 access 토큰의 수명이 다하면 refresh 토큰을 보내고 서버는 그걸 데이터베이스에 비교해보고 맞다면 새 access 토큰을 발급해준다. 이제 이 refresh 토큰만 안전하게 관리된다면 이게 유효할 동안은 access 토큰이 만료 될 때마다 다시 로그인을 할 필요 없이 액세스 토큰을 새로 발급 받는다.
매번 인가를 받을 때 마다 쓰는 짧은 수명의 토큰 = 엑세스 토큰
이 엑세스 토큰을 재발급 받을 때 쓰는 거 = 리프레시 토큰
누군가 엑세스 토큰을 탈취해도 수명이 짧고,
누군가의 로그인을 다시 시도하게 하고 싶다면 상응값을 db에서 지워 토큰갱신이 안되게 하면 된다.