쿠키와 세션 방식의 큰 문제점은,
세션은 서버의 자원을 사용하는데 사용자가 많아질수록 메모리를 차지하므로 비효율적이고,
서버 확장시 서버간에 세션을 공유하기 어렵다는 것이다.
이 문제를 보완하기 위해
'요청과 응답안에 사용자의 상태를 담아서 사용자의 인증과 인가를 처리해보자' 라는 아이디어가 나왔다.
그렇게 나온것이 Token을 활용한 인증 방식이다.
그 중 JWT(JSON WEB TOKEN)이라는 하나의 표준 인증 방식에 대해 알아보자.
토큰 기반의 인증 방식을 사용한다.
토큰은 로그인 후 서버가 클라이언트에 넘겨주는 랜덤한 문자열이다.
이 문자열은 사용자 정보가 암호화 되어있고 이 토큰을 이용해 인증된 사용자인지 서버가 판단할 수 있다.
1) 로그인 요청을 보낸다.
2) DB를 확인해서 유저인지 체킹한다.
3) 서버는 secret 키를 이용해서 토큰을 만든다.
4) 토큰을 응답헤더에 실어서 클라이언트에 보낸다.
5) 클라이언트는 토큰을 브라우저의 스토리지에 저장해 두었다가 요청을 할 때 그 토큰을 요청헤더에 같이 실어 보낸다.
6) 서버는 받은 토큰의 유효성 검사를 본인이 가진 secret 키로 한다.
7) 토큰이 유효하다면 사용자의 정보를 파악한다. 어떤 유저인지, 만료된 토큰인지, 권한이 있는 사용자인지 체크한다.
장점
사용자 인증에 필요한 정보는 토큰 자체에 포함되기 때문에 별도의 인증 저장소가 필요없다.
트래픽에 대한 부담이 낮다.
단점
access token 을 탈취당하면 해커가 사용자의 자원에 접근할 수 있다.
이것을 막기 위해 만료 기한을 정하는데, 만료 기한이 지나면 사용자도 사용할 수 없게 되므로 다시 로그인 해야하는 불편함이 있다.
이 문제를 해결하기 위해 나온 것이 refresh token 이다.
1) 로그인 요청을 보낸다.
2) DB를 확인해서 유저인지 체킹한다.
3) 서버는 secret 키를 통해서 access token, refresh token 를 만든다. access token 는 따로 저장소에 저장하지 않고
refresh token만 저장한다.
4) 두 가지 토큰을 한번에 응답 헤더로 보내면 클라이언트가 둘 다 저장을 한다.
5) 클라이언트가 access token을 실어서 요청을 보낸다.
6) 시간이 지나서 access token이 만료가 되었는데 사용자는 만료된 사실을 모르기 때문에 요청을 또 보낸다.
7) 서버는 '토큰이 만료됐다'고 말한다. 그때 브라우저는 refresh token를 서버로 보낸다.
8) 서버는 받은 refresh token을 참고해서 DB를 체킹하여 유저가 맞다면 새로 갱신한 access token을 보낸다. 그럼 클라이언트에서도 업데이트된 access token을 사용할 수 있게 된다.