세션 기반 인증은 서버(혹은 DB)에 유저 정보를 담는 인증 방식이였다
서버에서 유저가 민감하거나 제한된 정보를 요청할 때마다
즉, 인증이 필요하거나 권한 확인이 필요한 순간마다 "요청을 구한 유저에게 우리가 정보를 줘도 괜찮은가?" 에 대한 확인을 하기위해 가지고 있는 세션 값과 일치하는지 확인한다
하지만 매번 요청마다 데이터베이스를 확인하는것은 불편하고, 부담이 되는 작업이다 그것을 효율적이고 나은 방식으로 대체하는것이 바로 JWT(JSON Web Token) 이다
토큰은 쉽게 입장권이라고 이해하는것이 편한거 같다
우리가 놀이동산에 갔을때 표를 끊고 손목에 착용하는데, 놀이기구를 탑승하기전 표를 보여주는 것만으로 확인 절차를 손쉽게 줄일수 있지 않는가? 일일이 모든 놀이기구마다 절차를 요구하는 것이 아닌 표(토큰)을 확인해 쉽게 진행이되니.
JWT는 보통 2가지로 나뉜다
액세스 토큰은 보호된 정보 (유저의 이메일, 연락처, 사진 등)에 접근할 수 있는 권한부여에 사용한다
클라이언트가 처음 인증을 받게 될 때 (ex. 로그인), 액세스 토큰과 리프레시 토큰 두 가지를 모두 받지만,
실제로 권한을 얻는데 사용하는 것은 '액세스 토큰'이다
이에 대해 의문점이 생긴다 그럼 액세스 토큰만 받으면 되지않는가?
그렇다, 권한을 부여받는데 액세스 토큰만 가지고 있으면 된다
하지만 만약 액세스 토큰을 악의적인 유저가 얻어낸다면?
그 유저는 자신이 다른 유저인 것 마냥 서버에 여러 가지 요청을 보낼 수 있다
만약 금전적인 문제라면? 큰 문제가 발생할것이다.
그래서 액세스 토큰에는 비교적 짧은 유효 기간을 주어 탈취되어도 오랫동안 사용할 수 없게 하는 것이 좋다.
짧은 유효기간으로 액세스 토큰이 만료되면 리프레시 토큰을 사용해 새로운 액세스 토큰을 발급받는다
리프레시 토큰도 탈취 당한다면?
유효기간이 긴 리프레시 토큰마저 악의적인 유저에게 탈취된다면 큰 문제가 될 것이다.
상당히 오랜 기간 동안 액세스 토큰이 만료되면 다시 발급받으며 유저에게 피해를 입힐수 있기 때문이다
그렇기에 유저의 편의보다 정보를 지키는것을 중요시한 웹사이트들은 리프레시 토큰을 사용하지 않는 곳도 많다고 한다
.
을 기준으로 3부분이 존재한다
{
"alg":"HS256",
"typ":"JWT"
}
{
"sub": "someInformation",
"name": "phillip",
"iat": 151623391
}
base64 인코딩 자체는 누구나 쉽게 디코딩 할 수 있어 Header 와 Payload 모두 쉽게 확인이 가능하지만
비밀키를 사용해 이를 암호화한 값은 비밀키를 보유한게 아니면 해독하는데 많은 시간과 노력이 필요하다
HMAC SHA256 알고리즘
HMACSHA256(base64UrlEncode(header) + '.' + base64UrlEncode(payload), secret);
JWT를 통한 인증의 장점
안전한다
암호화한 받은 토큰을 사용하고, 암호화 키를 노출할 필요가 없기 때문에 안전하다
어디서나 생성 가능하다
토큰을 확인하는 서버가 토큰을 만들어야 하는 법은 없다, 토큰 생성용 서버를 만들거나, 다른 회사에 토큰 관련 작업을 맡기는 등 다양하게 활용할 수 있다.
권한 부여에 용이하다
토큰 내용물 즉 Payload 안에 해당 유저가 어떤 정보에 접근 가능한지 정할 수 있다.
Payload는 해독할 수 있다.
Payload는 base64로 인코딩 되어있다, 토큰을 탈취하여 페이로드를 해독하면 토큰 생성시 저장한 데이터를 확인할 수 있다.
그러니 페이로드엔 중요한 정보를 담지 않아야 한다.
토큰의 길이가 길어지면 네트워크에 부하를 줄 수 있다.
토큰에 저장하는 정보의 양이 많아질수록 토큰의 길이가 길어진다, 요청마다 길이가 긴 토큰을 함께 전송하면 네트워크에 부하를 줄 수 있다.
토큰은 자동 삭제가 되지 않는다.
JWT 장점 중 하나인 Stetelessness이 존재한다 즉, 상태를 저장하지 않기 때문에 한 번 생성된 토큰은 자동으로 삭제되지 않는다 그러니 꼭 토큰 만료 시간을 추가해야한다
또한 토큰이 탈취된 경우 토큰의 기한이 만료될 때까지 대처가 불가하다 주의해서 토큰 만료 기간을 설정해야한 너무 길지않게
토큰은 어딘가에 저장되어야 한다
토큰은 클라이언트가 가지고 있다가 인증이 필요한 요청을 보낼때마다 함께 전송할 수 있어야 한다.