하나의 웹사이트에는 수많은 사용자들이 있다. 각 사용자들은 원하는 데이터도 다르고 가지고 있는 컨텐츠도 모두 다르다. 서버는 사용자의 요청에 맞춰 데이터를 전송해야 하는데, 이 때 서버는 요청을 보낸 사용자가 누군지 정확하게 알 필요가 있다. 사용자가 누군지 확인을 정확히 하지 않는다면 나의 정보는 타인에게 유출될 것이다. 그러므로 클라이언트에서 요청을 보낼 때, 자신이 누구인지 알만한 단서를 서버에게 보내줘야 한다.
마치 배민에서 포장 주문을 하고 식당을 찾아갔는데 본인을 증명할 수단(주문 번호, 배민 닉네임 등)이 없다면 어떻게 될까? 식당 주인은 이 사람이 주문한 사람이 맞는지 확신하지 못하므로 음식을 선뜻 주지 못할 것이다. 이를 해결하기 위해선 본인을 증명할 수단이 필요하다.
현재 웹에서 가장 많이 쓰이는 통신 방식은 http 요청 방식이다. http 요청 데이터는 크게 헤더와 바디로 구성되어 있다. 헤더에는 요청에 대한 정보를 포함하고, 바디에는 요청 내용이 포함된다. 일반적으로 인증 정보는 헤더에 넣어 요청을 보내게 된다
다시 포장 주문을 예시로 들면 헤더는 주문 번호를 포함하고, 바디는 무엇을 주문했는지를 포함한다.
사용자 인증 방식에는 위와 같이 크게 두 가지 방식이 있다.
토큰 방식에서 더 나아가서 OAuth와 같은 방식이 있다.
근데.. 아이디 패스워드만 입력하면 되는거 아닌가?
분명 로그인 할 때 아이디와 패스워드를 통해 인증을 했는데 세션이나 토큰같은건 왜 사용할까? 그 이유는 브라우저에 로그인 정보를 저장하고 유지시키기 위해서 사용한다. 서버로 새로운 데이터를 요청할 때마다 아이디와 패스워드를 입력하면 매우 불편할 것이다. 이 불편함을 없애기 위해 처음에만 아이디 패스워드를 입력하고 세션이나 토큰을 발급받아 브라우저에 저장을 해서 일정 기간 동안 유지시킨다. 이 인증 정보는 서버로 요청을 할 때마다 사용한다.
초기에는 계정 정보(아이디, 패스워드 등)를 요청 데이터에 포함해서 보냈다.
이 방식은 보안에 매우 취약했고, 이를 보안하기 위해 새롭게 등장한 것이 세션/쿠키 방식이다.
세션/쿠키 방식의 순서는 다음과 같다.
JWT 방식은 Json Web Token의 약자로 인증에 필요한 정보들을 암호화시킨 토큰을 뜻한다.
클라이언트는 토큰을 HTTP 헤더에 실어서 서버 요청을 하게 된다.
세션/쿠키 방식은 사용자별 세션ID를 서버의 저장소에 저장하는 반면, 토큰 방식은 토큰 자체에 인증에 필요한 정보들을 암호화 시켜서 저장한다.
쉽게 얘기해서 어떤 기관에서 행사를 한다고 했을 때,
세션/쿠키 기반 방식은 기관에서 이용객들의 정보를 담은 장부를 통해 관리하는 느낌이고,
토큰 기반 방식은 이용객들에게 티켓을 나눠줘서 이용하게끔 관리하는 느낌이다.
비유가 맞는진 모르겠다..
토큰 기반 방식의 순서는 다음과 같다.
토큰 방식의 경우 해커한테 토큰이 뚫릴 경우 유효기간이 끝날 때까지 막을 수 없다는 단점이 있었다. 이를 막기 위해 유효기간을 짧게 설정한다면 사용자는 로그인을 자주해야 하므로 불편함을 초래한다.
이를 막기 위해 Refresh 토큰 방식을 도입했다. 이 방식은 Access 토큰의 유효기간은 짧게 설정하고, Refresh 토큰의 유효기간은 길게 설정한다. 클라이언트는 길게 설정된 Refresh 토큰의 경우 더 안전한 저장소에 저장하고, Access 토큰을 헤더에 실어 서버에 요청한다. Access 토큰이 만료되었을 경우 Refresh 토큰을 사용해 새로 발급받는다.
이 방식을 사용하면 Access 토큰이 탈취 당해도 짧은 유효기간 때문에 더 안전하고, 로그인 빈도도는 더 적게 할 수 있어서 보안과 사용자 편의 둘 다 모두 챙길 수 있다.