JWT

woolim park·2021년 4월 10일
0

JWT

구조

점(.)으로 분리된 3부분으로 구성 (header, payload, verify signature)

  1. header
  • 토큰 타입
  • signing algorithm
{
  "alg": "HS256",
  "typ": "JWT"
}

이후 header 부분은 Base64URL로 인코딩된다.

  1. payload
  • registered claims: iss(issuer), exp(expiration time), sub(subject), aud(audience) and etc. It is not mandatory but recommended.

  • public claims

  • private claims

이후 payload는 Base64URL로 인코딩된다. 민감한 정보는 디코딩이 가능하므로 담으면 안된다.

  1. signature

header와 payload가 각각 base64인코딩된 것을 점으로 이어 붙인뒤 본인이 header에 명시한 알고리즘으로 시크릿과 함께 signature를 만든다. 그 후 base64로 인코딩한다.

const secret = "..."
const headerAndPayload = base64UrlEncode(header) + "." + base64UrlEncode(payload);

const signature = crypto.createHmac('sha256', secret).update(headerAndClaimSet).digest('base64')

특징

  1. 기존의 토큰방식은 데이터베이스(또는 서버캐시)에 저장하고 유효성을 검사해야했다면, jwt는 토큰만 가지고 유효성검사나 사용자 식별까지 할 수 있으므로 서버를 무상태로 유지하는 것이 가능하다.

  2. 클레임셋이 암호화되지 않으므로 민감하지 않은 최소한의 정보만 클레임셋에 담아야한다.

  3. 클레임셋의 길이가 길면 토큰의 길이도 길어진다.

  4. 토큰이 탈취되면 답이 없다.

Best practice

여러가지 방법이 있지만 그 중 가장 낫다고 생각하는 방식은 access / refresh token.

  1. access token 의 만기를 15분
  2. refresh toekn 의 만기를 3일
  3. access token 는 웹어플리케이션 메모리영역에 저장하고(cookie, localStorage에 저장X), refresh token 은 보안된 쿠키(secure, samesite, httponly)에 저장한다.
  4. access token 은 HTTP 요청을 보낼때마다 header Authorization Bearer jwt_token 에 추가해서 보낸다. access token은 쿠키에 저장할 필요가 없으므로 Cross-Origin Resource Sharing (CORS), SameSite 이슈로 부터 자유롭다.
  5. access token이 만기되면 token refresh 요청을 보내고 새로운 access token, refresh token 을 부여받는다.

Nuxt같은 SSR에서는 API서버와 SameSite가 아닌 경우, Refresh Token이 SameSite 쿠키이기 때문에 token refresh를 Nuxt Server 에서 담당해야한다.

profile
Javascript Developer

0개의 댓글