기존에 인증을 받는 절차는 따로 내가 어떠한 기술을 적용하지 않는다면, 세션 을 활용하여 쿠키로 인증을 받게 된다.
따로 복잡하게 알아볼 필요 없이, 현재 사용하는 브라우저에 쿠키를 조회할 수 있는 플러그인이 설치되어있다면, 그걸로 조회를 해보면 된다.
Velog 는 이렇게 토큰을 활용해 인증을 하는것 같다.
네이버 블로그에서 쿠키를 조회해보면 JSESSIONID 라는 쿠키가 조회된다.
우리가 기존에 스프링 시큐리티를 이용하여 자체 폼 로그인을 이용하면, 네이버 블로그와 마찬가지로 JSESSIONID 쿠키로 인증을 받게 된다.
그러면 웹사이트마다, 각각 다른 방법으로 인증처리를 하는거 같은데, 이렇게 세션을 활용한 인증처리의 장단점을 알아보자.
장점
내가 저 위에 스크린샷의 값을 노출시켜도 나의 정보가 유출되는건 아니란 소리이다.
단점
세션의 단점을 해결하기 위해서 토큰으로 인증하는 방법을 사용할 수 있다.
유저가 로그인을 하면 서버에서는 토큰을 생성한 뒤에 저장하지 않고 (stateless) 토큰 값을 전달해준다.
컴퓨팅에서 무상태 프로토콜(stateless protocol)은 어떠한 이전 요청과도 무관한 각각의 요청을 독립적인 트랜잭션으로 취급하는 통신 프로토콜로, 통신이 독립적인 쌍의 요청과 응답을 이룰 수 있게 하는 방식이다.
서버는 유저의 정보가 살짝 담긴 이 토큰으로 유저가 무언가를 요청할때마다 토큰의 값을 해석해 유저를 인증한다.
단순히 말하자면 토큰을 이용한 인증처리는 유저가 로그인을 하는 순간부터 티켓을 부여받아 해당 티켓으로 놀이기구를 탈 수 있는것이다.
JWT는 Json Web Token 의 줄임말이다. (존맛탱 토큰 아님)
JWT는 HEADER , PAYLOAD , SIGNATURE 이렇게 머리 몸통 다리 로 이루어져있다.
HEADER 는 JWT를 검증하는데 필요한 정보를 가진 객체이다.
Signature에 사용한 암호화 알고리즘이 무엇인지, Key ID가 무엇인지 정보를 담고 있다.
이 정보를 Json으로 변환해서 UTF-8로 인코딩한 뒤 Base64 URL-Safe 로 인코딩한 값이 들어가 있다. (암호처럼 보이지만 암호화된 값은 아니라고 한다.)
존맛탱 토큰의 PAYLOAD에는 인증에 필요한 데이터를 담고있다.
데이터의 각각 필드를 Claim 이라고 한다. 인증할때 payload 에 있는 username 을 가져와서 유저 정보를 조회할때 사용해야 하기 떄문이다.
그리고 토큰의 발행시간과 만료시간을 포함한다.
원하는 정보를 더 담을 수 있지만, 민감 정보는 포함시키면 안된다.
PAYLOAD 역시 암호화되지 않은 정보이다.
Header 와 Payload 에는 암호화되지 않고 인코딩된 값이 들어가있다면, Signature 에는 토큰 자체의 진위여부를 판단하는 용도로 사용되기 때문에 Header 와 Payload 를 합친 뒤에 비밀키로 hash 를 생성하여 암호화한다.
Secret Key 가 노출되어 데이터가 유출될 상황을 방지하기 위해 Secret Key 를 여러게 두고 Key 노출에 대비할 수 있다.
Secret Key를 여러개를 사용하고 수시로 추가 삭제 해줘서 변경을 해주면, 키들중에 하나가 노출되어도 다른 Secret Key 와 데이터는 안전한 상태가 된다.
이걸 Key Rolling 이라고 한다.
JWT 토큰을 만들 때 헤더에 key id 를 포함하여 제공하고, 서버에서 해석할때 key id 로 Secret Key 를 찾아서 Signature 를 검증한다 .
장점
단점
하지만 토큰을 이용한 인증처리에는 해당 단점들을 보완할 수 있는 여러 방안이 존재한다.
대표적으로 단순히 하나의 토큰을 이용해 인증을 받는 방식이 아닌 2개의 토큰을 이용한 인증처리 방식이 있다고 한다.
쉽게 알아보는 서버 인증 2편(Access Token + Refresh Token)
(정리가 잘 되어있는 글이다. 댓글도 읽다보면 의견 공유가 잘되있는 글이라 한번 참고하면 큰 도움이 될것 같다.)
만료 기한이 훨씬 긴 리프레쉬 토큰과 짧은 만료 기한을 가진 액세스 토큰을 로그인 시에 발급시켜주고, 만료기한이 지나면 액세스 토큰이 없어진다.
-> 유저의 액세스 토큰이 만료되고 유저는 로그아웃을 아직 하지 않았을때 사이트를 이용한다면, 서버는 유저의 리프레쉬 토큰을 확인후에 새로운 만료기한을 가진 액세스 토큰을 발급해 사이트를 이용할 수 있게 인증을 해주는것이다.
(짧게 예를 들자면 유저는 놀이공원 입장시에 본인의 핸드폰으로 큐알코드를 발급받아 큐알코드로 리프레쉬 토큰 역할을 하고, 한시간마다 큐알코드를 토대로 기구 탑승에 필요한 티켓을 발급받는거라고 생각하면 쉽다. 놀이공원 퇴장시에 큐알코드와 티켓은 만료되어 사용할 수 없다.)
다음 글에선 공부한걸 바탕으로 직접 토큰을 활용한 인증방식을 구현해보자!