JWT

Mixer·2022년 7월 27일
0

토큰 기반 인증? 언제 사용하나?

세션 기반 인증은 서버(혹은 DB)에 유저 정보를 담는 인증 방식이였다
서버에서 유저가 민감하거나 제한된 정보를 요청할 때마다
즉, 인증이 필요하거나 권한 확인이 필요한 순간마다 "요청을 구한 유저에게 우리가 정보를 줘도 괜찮은가?" 에 대한 확인을 하기위해 가지고 있는 세션 값과 일치하는지 확인한다
하지만 매번 요청마다 데이터베이스를 확인하는것은 불편하고, 부담이 되는 작업이다 그것을 효율적이고 나은 방식으로 대체하는것이 바로 JWT(JSON Web Token) 이다

토큰은 무엇인가?

토큰은 쉽게 입장권이라고 이해하는것이 편한거 같다
우리가 놀이동산에 갔을때 표를 끊고 손목에 착용하는데, 놀이기구를 탑승하기전 표를 보여주는 것만으로 확인 절차를 손쉽게 줄일수 있지 않는가? 일일이 모든 놀이기구마다 절차를 요구하는 것이 아닌 표(토큰)을 확인해 쉽게 진행이되니.

JWT 란?

JWT는 보통 2가지로 나뉜다

  1. 액세스 토큰(Access Token)
  2. 리프레시 토큰(Refresh Token)

액세스 토큰은 보호된 정보 (유저의 이메일, 연락처, 사진 등)에 접근할 수 있는 권한부여에 사용한다
클라이언트가 처음 인증을 받게 될 때 (ex. 로그인), 액세스 토큰과 리프레시 토큰 두 가지를 모두 받지만,
실제로 권한을 얻는데 사용하는 것은 '액세스 토큰'이다

이에 대해 의문점이 생긴다 그럼 액세스 토큰만 받으면 되지않는가?

그렇다, 권한을 부여받는데 액세스 토큰만 가지고 있으면 된다
하지만 만약 액세스 토큰을 악의적인 유저가 얻어낸다면?
그 유저는 자신이 다른 유저인 것 마냥 서버에 여러 가지 요청을 보낼 수 있다
만약 금전적인 문제라면? 큰 문제가 발생할것이다.
그래서 액세스 토큰에는 비교적 짧은 유효 기간을 주어 탈취되어도 오랫동안 사용할 수 없게 하는 것이 좋다.
짧은 유효기간으로 액세스 토큰이 만료되면 리프레시 토큰을 사용해 새로운 액세스 토큰을 발급받는다

리프레시 토큰도 탈취 당한다면?

유효기간이 긴 리프레시 토큰마저 악의적인 유저에게 탈취된다면 큰 문제가 될 것이다.
상당히 오랜 기간 동안 액세스 토큰이 만료되면 다시 발급받으며 유저에게 피해를 입힐수 있기 때문이다
그렇기에 유저의 편의보다 정보를 지키는것을 중요시한 웹사이트들은 리프레시 토큰을 사용하지 않는 곳도 많다고 한다

JWT 구조

.을 기준으로 3부분이 존재한다

  1. Header
    어떤 종류의 토큰인지(현재는 JWT), 어떤 알고리즘으로 sign할지 기술되어있다
    JSON Web Token이라는 이름에 맞게 JSON 형태를 볼수 있다.
{
  "alg":"HS256",
  "typ":"JWT"
}
  1. Payload
    페이로드엔 서버에서 활용할 수 있는 유저의 정보가 담겨있다
    어떤 정보에 접근 가능한지에 대한 권한을 담을 수 있고, 사용자의 유저 이름 등 필요한 데이터를 담을수도 있다.
    페이로드는 Signature를 통해 유효성이 검증될 정보이긴 하지만, 너무 민감한 정보는 삼가하자
{
	"sub": "someInformation",
    "name": "phillip",
    "iat": 151623391
}
  1. Signature
    base64로 인코딩된 첫 번째, 그리고 두번째 부분이 작성되었다면, Signature에서 원하는 비밀 키(암호화에 추가할 salt)와 Header에서 저장한 알고리즘을 사용해 암호화 한다.

base64 인코딩 자체는 누구나 쉽게 디코딩 할 수 있어 Header 와 Payload 모두 쉽게 확인이 가능하지만
비밀키를 사용해 이를 암호화한 값은 비밀키를 보유한게 아니면 해독하는데 많은 시간과 노력이 필요하다

HMAC SHA256 알고리즘
HMACSHA256(base64UrlEncode(header) + '.' + base64UrlEncode(payload), secret);

JWT 장점 && 단점

JWT를 통한 인증의 장점

  1. 무상태성과 확장성(Stetelessness & Scalability)의 특징을 가지고 있다
  • 서버는 클라이언트에 대한 정보를 저장할 필요가 없다 (토큰 해독이 되는지만 판단)
  • 클라이언트는 새로운 요청을 보낼 때마다 토큰을 헤더에 포함시키면 된다.
    만약 서버를 여러 개 가지고 있는 서비스라면 더더욱 효과를 본다, 같은 토큰으로 여러 서버에서 인증이 가능하기 때문에,
    하지만 세션 방식이라면 모든 서버가 해당 유저의 정보를 공유해야한다
  1. 안전한다
    암호화한 받은 토큰을 사용하고, 암호화 키를 노출할 필요가 없기 때문에 안전하다

  2. 어디서나 생성 가능하다
    토큰을 확인하는 서버가 토큰을 만들어야 하는 법은 없다, 토큰 생성용 서버를 만들거나, 다른 회사에 토큰 관련 작업을 맡기는 등 다양하게 활용할 수 있다.

  3. 권한 부여에 용이하다
    토큰 내용물 즉 Payload 안에 해당 유저가 어떤 정보에 접근 가능한지 정할 수 있다.

단점

  1. Payload는 해독할 수 있다.
    Payload는 base64로 인코딩 되어있다, 토큰을 탈취하여 페이로드를 해독하면 토큰 생성시 저장한 데이터를 확인할 수 있다.
    그러니 페이로드엔 중요한 정보를 담지 않아야 한다.

  2. 토큰의 길이가 길어지면 네트워크에 부하를 줄 수 있다.
    토큰에 저장하는 정보의 양이 많아질수록 토큰의 길이가 길어진다, 요청마다 길이가 긴 토큰을 함께 전송하면 네트워크에 부하를 줄 수 있다.

  3. 토큰은 자동 삭제가 되지 않는다.
    JWT 장점 중 하나인 Stetelessness이 존재한다 즉, 상태를 저장하지 않기 때문에 한 번 생성된 토큰은 자동으로 삭제되지 않는다 그러니 꼭 토큰 만료 시간을 추가해야한다
    또한 토큰이 탈취된 경우 토큰의 기한이 만료될 때까지 대처가 불가하다 주의해서 토큰 만료 기간을 설정해야한 너무 길지않게

  4. 토큰은 어딘가에 저장되어야 한다
    토큰은 클라이언트가 가지고 있다가 인증이 필요한 요청을 보낼때마다 함께 전송할 수 있어야 한다.

profile
Minthug'life

0개의 댓글