tokens

Auth0 Tokens

Auth0에서 인증(authentication)과 권한 부여(authorization)에 쓰이는 토큰은 크게 ID TokenAccess Token 두 종류로 나뉘어요. ID Token은 애플리케이션이 사용자를 식별할 때 사용하고, Access Token은 API가 요청한 작업을 수행할 수 있도록 권한을 알려줘요. 이 문서에서는 두 토큰의 역할과 구조, 그리고 Refresh Token 같은 특수 목적 토큰을 함께 설명할게요.

출처: 문서

본문

ID Token

ID Token은 애플리케이션에서만 사용하도록 만들어진 JWT(JSON Web Token) 예요. 예를 들어 사용자가 Google 계정으로 로그인하고 일정을 동기화하는 앱이 있다면, Google은 앱에 사용자 정보가 담긴 ID Token을 보내줘요. 앱은 이 토큰의 내용을 파싱해서 이름이나 프로필 사진 같은 정보를 바탕으로 사용자 경험을 맞춤화할 수 있어요.

  • ID Token에 담긴 정보를 사용하기 전에는 반드시 검증(validate) 해야 해요. 검증은 라이브러리를 이용해 손쉽게 처리할 수 있어요.
  • ID Token은 API에 접근하는 데 사용하면 안 돼요. 토큰마다 의도된 대상(audience, 보통 수신자)에 대한 정보가 담겨 있는데, OpenID Connect 규격에 따르면 ID Token의 대상(aud 클레임)은 인증 요청을 보낸 애플리케이션의 client ID여야 해요. 그렇지 않다면 그 토큰은 신뢰하지 않는 것이 맞아요.

디코딩된 ID Token의 내용은 다음과 같이 생겼어요.

{
  "iss": "https://your-domain.auth0.com/",
  "sub": "auth0|1234567890",
  "aud": "1234567890abcdef",
  "exp": 1313871970,
  "iat": 1313870970,
  "name": "Jane Doe",
  "picture": "https://example.com/avatar.jpg"
}

이 토큰은 사용자를 애플리케이션에 인증해 주는 역할을 해요. 토큰의 대상(aud 클레임)이 애플리케이션의 식별자로 설정되어 있으므로, 이 특정 애플리케이션만 이 토큰을 소비할 수 있어요.

반대로 API는 aud 값이 자기 자신의 고유 식별자와 동일한 토큰을 기대해요. 따라서 애플리케이션과 API를 모두 통제하고 있지 않는 한, ID Token을 API에 보내는 것은 대개 동작하지 않아요. ID Token은 API가 서명한 것이 아니기 때문에, API가 이 토큰을 받아들인다면 애플리케이션이 토큰을 수정했는지(예: scope를 더 추가했는지) 알 방법이 없거든요. 더 자세한 내용은 JWT Handbook을 참고하세요.

Access Token

Access Token(항상 JWT인 것은 아니에요)은 토큰을 가진 사람(bearer)이 해당 API에 접근할 권한을 부여받았고, 부여된 scope가 지정한 사전 정의된 작업을 수행할 수 있음을 API에 알려주는 데 사용해요.

앞선 Google 예시에서, 사용자가 로그인하고 Google 캘린더를 읽거나 쓸 수 있는 동의(consent)를 하면 Google은 앱에 Access Token을 보내줘요. 앱이 Google 캘린더에 쓰려고 할 때마다 HTTP Authorization 헤더에 Access Token을 포함해 Google Calendar API에 요청을 보내는 방식이에요.

  • Access Token을 인증(authentication)에 절대 사용하면 안 돼요. Access Token은 사용자가 인증되었는지 여부를 알려주지 못해요. Access Token이 가진 유일한 사용자 정보는 sub 클레임에 담긴 사용자 ID뿐이에요.
  • 애플리케이션에서는 Access Token을 불투명한 문자열(opaque string) 처럼 취급해야 해요. API를 위한 것이기 때문이에요. 애플리케이션은 이 토큰을 디코딩하려 하거나 특정 형식의 토큰을 기대해선 안 돼요.

Access Token의 예시는 다음과 같아요.

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3lvdXItZG9tYWluLmF1dGgwLmNvbS8iLCJzdWIiOiJhdXRoMHwxMjM0NTY3ODkwIiwiYXVkIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9hcGkiLCJpYXQiOjEzMTM4NzA5NzAsImV4cCI6MTMxMzg3MTk3MCwic2NvcGUiOiJyZWFkOmNhbGVuZGFyIn0.pQ8TjUjWbE9Sy1U6cXjY4QwZ9f0jQ8Y2p1a0b3c4d5e6f7g

이 토큰은 사용자에 대해 sub 클레임에 담긴 ID 외에는 어떤 정보도 포함하지 않아요. 단지 애플리케이션이 API에서 수행할 수 있는 작업(scope 클레임)에 대한 권한 정보만 담고 있어요. 그래서 이 토큰은 API를 보호하는 데는 유용하지만, 사용자를 인증하는 데는 쓸 수 없는 거예요.

상황에 따라 sub 클레임 외에도 사용자에 대한 추가 정보나 커스텀 클레임을 Access Token에 담고 싶을 수 있어요. 그러면 API가 사용자 정보를 가져오기 위해 추가 작업을 하지 않아도 되거든요. 다만 이렇게 하면 그 추가 클레임들이 Access Token에서 읽혀질 수 있다는 점을 명심해야 해요. 자세한 내용은 Create Custom Claims를 참고하세요.

특수 목적 토큰(Specialized Tokens)

Auth0의 토큰 기반 인증 시나리오에는 세 가지 특수 목적 토큰이 있어요.

  • Refresh Token : 사용자를 다시 인증하지 않고도 새로운 Access Token을 얻는 데 사용하는 토큰이에요.
  • IDP access token : 사용자 인증 후 신원 제공자(identity provider)가 발급한 Access Token으로, 타사 API를 호출할 때 사용할 수 있어요.
  • Auth0 Management API access token : 특정 클레임(scope)을 담고 있는 수명이 짧은 토큰으로, Management API 엔드포인트를 호출할 수 있게 해줘요.

JWT 구조와 검증

ID Token과 (JWT 형식의) Access Token은 모두 세 부분(헤더, 페이로드, 서명) 으로 이뤄진 JWT 구조를 가져요.

header.payload.signature
  • Header : 토큰의 타입과 서명에 사용된 알고리즘 정보를 담아요.
  • Payload : sub, aud, exp, iat, scope 같은 클레임(주장)을 담아요.
  • Signature : 헤더와 페이로드를 비밀 키로 서명한 값으로, 토큰이 위조·변조되지 않았는지 검증하는 데 사용해요.

토큰을 사용하기 전에 반드시 검증해야 해요. 검증 시에는 서명(signature) 확인, 만료 시간(exp) 확인, 대상(aud) 확인이 핵심이에요. 각각의 토큰 유형별 상세 규칙은 아래의 관련 문서를 참고하세요.

더 알아보기 (Learn more)