세션을 기반으로 하는 인증 시스템은 정보를 서버(혹은 데이터베이스)에 담아 보관합니다. 클라이언트는 세션 id 를 받았다가 다시 전달할 뿐이고, 세션 id 를 기반으로 유효한지를 비교탐색하는 작업은 오롯이 서버가 감당해야 하는 일이죠.
이는 서버 입장에서는 많이 부담이 되는 일입니다. 서버는 다수의 클라이언트를 동시에 (엄밀한 의미에서는 빠르게 전환해가면서) 처리해야 하기 때문이죠. 서버의 부담을 줄이려면 다른 방법을 찾을 필요가 있습니다.
토큰 기반 인증은 서버의 부담을 줄일 수 있는 대안이 될 수 있습니다. 왜냐하면 클라이언트에다가 인증에 관한 정보를 보관하도록 고안되었기 때문입니다. 근데 과연 안전한 방식일까요? 보안이 보장되지 않는다면 인증의 의미가 퇴색될테니 말입니다.
토큰은 암호화를 사용해 데이터를 저장하기 때문에, 노출이 되어도 그 안에 담긴 정보를 알 수 없습니다. 토큰 그 자체가 탈취될 수도 있는 상황을 고려해 유효기간을 짧게 잡는다고도 하네요.
토큰 기반 인증에 여러가지가 있다고 하는데요. 제가 공부한 것은 JWT (JSON Web Token) 이라고 불리는 것입니다. 위키백과의 설명에 따르면 인터넷 표준 중 하나라고 하네요.
'일반적으로 인터넷 표준은 안정적이고 이해하기 쉬운 사양이며, 기술적으로 유용하고, 상호 독립적이고 혼용이 가능한 여러 구현 및 이를 통한 실질적인 운영 경험을 보유하였으며, 상당한 대중의 공개된 지지를 얻고 있고 인터넷의 일부 또는 모든 부문에서 유용하다고 인식되는 규격이다.'
JWT 에서 토큰은 2 가지로 나뉜다고 합니다. Access Token 과 Refresh Token 입니다. Access Token 으로 권한을 얻게 된다면 Refresh Token은 Access Token 이 만료되었을 경우 다시 권한을 얻을 때 사용됩니다.
당연히 Access Token 과 Refresh Token, 이 둘 중에서는 Access Token 의 유효기간이 더 짧게 설정됩니다. 그래야 Access Token 이 만료되더라도 Refresh Token 으로 새로운 Access Token 을 발급받아 권한을 이어나갈 수 있겠죠.
다만 Refresh Token 이 탈취당하면 더 오랜 기간 동안 유저의 인증이 탈취되는 것이기 때문에 유저의 인증이 중요하다면 경우에 따라서 Refresh Token 을 사용하지 않는 경우도 있다고 합니다.
노드에서 사용 가능한 모듈로 jsonwebtoken 모듈이 있습니다.
jwt.sign
메소드 를 이용해 토큰을 생성할 수 있고, jwt.verify
메소드 를 이용해 토큰을 검증할 수 있습니다. 여러 에러 핸들링에 관해서도 찾아보실 수 있지만, 일단은 앞에서 언급한 두 메소드를 활용하는 것이 가장 중요한 것 같습니다.