말 그대로 상태가 있냐 없냐인데, 그럼 의문점이 두 개가 생긴다.
보통 웹 페이지를 사용하려면 로그인을 해야 한다. 로그인에는 인증(Authentication)과 인가(Authorization)가 포함된다.
인증과 인가는 단순하게 말하면 다음과 같다.
그러니까 A가 웹 페이지를 사용하려면,
해야 하는 것이다.
이런 정보가 상태의 대표적인 예시다.
상태가 있냐 없냐의 기준은 서버다.
클라이언트의 정보를 서버에 저장하냐 안하냐의 차이이며, "stateful하다" ≡ "서버에 클라이언트 정보를 저장한다"가 성립한다.
예를 들어 한 번 로그인하면 나의 대한 정보를 서버에 저장해두는 방식이며, session이 대표적인 예.
일단 로그인하고 세션이 생성되었다면, 이후의 요청에서는 굳이 또 나를 증명하지 않는다(세션이 만료되지 않는 한).
요약) 한 번 말해두면 당분간 기억함
stateful과 반대다. 즉 "stateless하다" ≡ "서버에 클라이언트 정보를 저장하지 않는다"가 성립한다.
JWT; Json Web Token가 대표적인 예.
클라이언트의 인증 정보는 클라이언트에 저장한다. 그래서 요청에 인증 정보가 포함되어 들어오고, 서버는 여기서 요청자가 누군지 확인한다.
JWT에 사용자 식별자가 포함되어 온다면, 그 사용자는 인증된 사용자임을 확신한다.
이때 진짜 그 사람이 보낸 건지 확인하지 않고(인증은 하지 않고), 그 사람이 우리 서비스 사용자인지는 확인한다(인가는 한다).
요약) 말해도 기억을 안 해서 했던 말 또 해야 된다.
JWT를 사용한다면 다음과 같은 검증을 생각해볼 수 있다.
사용자 A의 정보가 담긴 토큰으로 글쓰기를 요청한다.
글쓰기 요청에는 다음이 포함된다.
- 토큰
- 작성자
- 게시글 제목
- 게시글 내용
이 경우 다음을 고려해봐야 한다.
토큰이 만료되었는가? 는 모든 요청에서 당연히 고려할 부분이니까 넘어가고, 토큰에 포함된 사용자 정보와 작성자 정보가 일치하는가?를 생각해보자.
이 부분을 만족하려면 다음과 같은 절차를 거쳐야 한다.
이걸 확인하는 건 토큰이 탈취된 상황을 고려하기 위함이다.
그런데 요청 시마다 요청을 검증하는 건 stateful에 가깝다.
stateless에서는 사용자 정보를 유지하지 않는 것이 핵심이다. 즉 서버 쪽에서 사용자 정보를 굳이 확인하는 게 아니라, 애초에 토큰을 잘 보냈어야 하는 것.
어느 유튜버의 비유에 따르면 '신용카드 잃어버리면 쓴 놈 잘못이지 발급한 놈 잘못이 아니다'.
즉 토큰을 발급한 서버에서는 탈취된 상황을 고려하지 않는 것이다.
물론 진짜 고려 안하면 망한다. 고객이 카드를 잃어버렸는데 아무런 조치도 취하지 않는 카드사는 매일 논란에 휩싸일 것이다.
그래서 access token과 refresh token으로 구분해 운용한다.
운용법은 이 블로그의 다른 글을 참고 바란다.
우선 생각해볼 만 한 건 서버를 여러 대 두는 상황이다.
일단 서버는 서버가 받은 요청에 포함된 인증 정보를 '믿는다'.
즉 일단 인증 정보 자체가 유효하다면(내가 발급했고, 아직 만료되지 않았고, ...) 그 인증 정보에 따라 응답한다.
인증 정보만 갖고 있다면 뭐든 할 수 있다는 맹점이 발생하는데, 인증 정보 탈취에 굉장히 취약해진다. 인증 정보의 유효성은 검사하지만 그 인증 정보가 누구의 것인지, 즉 보낸 사람의 것이 맞는지 모른다.
그래서 JWT는 access token과 refresh token, refresh token rotation이라는 귀찮은 운용 방법을 취하는 것이다.
HTTP의 헤더 중 Authorization이라는 게 있다.
이 헤더에 인증 정보를 담으면 CSRF로부터 안전한데, 이유는 다음과 같다.
그건 사용자 컴퓨터 자체가 털린 거라 JWT고 뭐고 답이 없는 상황입니다(출처)