오픈소스 개발기— (1) firebase-admin-node

Dave Kwon
5 min readSep 4, 2022

--

Overview

firebase-admin-node로 custom token을 만드는 과정에 impersonate service account를 사용할 수 없는 이슈

issue: https://github.com/firebase/firebase-admin-node/issues/1861
pr: https://github.com/firebase/firebase-admin-node/pull/1862

Contribute Status

[2022–09–05]
아직 accept은 되지 않았으나 소수의 사람들의 니즈가 있는 거 같긴하다. 아마 곧 머지되거나 피드백이 오지 않을까..

Reproduce

  1. custom token generate 권한이 있는 service-account를 만든다.
    필요한 권한은 다음을 참조한다 roles/iam.serviceAccountTokenCreator
  2. 해당 service-account를 이용해 gcloud ADC를 내려받는다.
$ gcloud auth application-default login --impersonate-service-account=<impersonate-service-account>

3. ~/.config/gcloud/application_default_credentials.json 에 해당 내용이 잘 들어갔는지 확인한다. 다음 포맷으로 생성이 될 것이다.

{
"delegates": [],
"service_account_impersonation_url": "",
"source_credentials": {
"client_id": "",
"client_secret": "",
"refresh_token": "",
"type": "authorized_user"
},
"type": "impersonated_service_account"
}

4. firebase-admin-node@10.2.0 를 다운받는다.

$ yarn add firebase-admin-node@10.2.0

5. firebase-admin-node를 실행한다.

import admin from 'firebase-admin';admin.initializeApp({
credential: admin.credential.applicationDefault(),
});

6. 에러 메시지 발생

message: 'Refresh token must contain a "client_id" property.'

How to solve

Cause Analysis

src/app/credential-internal.ts 을 보면, getApplicationDefault에서 필요한 credential을 받아오는 걸 확인할 수 있다.

우리는 env로 세팅을 해주지 않았기 때문에 아래 refreshToken 방식으로 생성하는 것을 볼 수 있다.

그러나 RefreshTokenCredential 은 아래 포맷을 따르는 걸 전제로 하고 있기에 오류가 날 수 밖에 없다.

firebase-admin-node는 impersonated_service_account 타입을 받아주지 않고 RefreshTokenCredential로 취급하여 처리하고 있던 것이다.

Solution

Impersonated ServiceAccount를 제대로 사용할 수 있도록 아래와 같이 Credential을 상속받는 ImpersonatedServiceAccountCredential을 만들어 준다.

물론, ServiceAccount 값들을 저장하는 ImpersonateServiceAccount 도 만들어 준다.

우리가 원하는 정보는 sourceCredentials에 있으므로 해당 내용을 뽑아서 사용하고, 나머지 access token을 받아오는 과정은 RefreshTokenCredential 과 동일하게 만든다. 이 부분은 google-auth-library-python에서 token을 만드는 과정을 참고했다.

마지막으로 type이 해당 타입일 때 ImpersonatedServiceAccountCredential 을 사용하도록 만든다.

테스트를 추가하고 마무리한다.

해당 내용은 상단 첨부한 PR에 있다.

--

--

Dave Kwon
Dave Kwon

No responses yet