커스텀 토큰 만들기

이 문서에서는 Identity Platform을 사용하여 커스텀 JSON 웹 토큰(JWT)을 만드는 방법을 보여줍니다.

커스텀 토큰을 사용하면 인증 프로세스를 완벽하게 제어할 수 있습니다. 토큰을 서버에서 생성한 뒤 클라이언트 기기에 다시 전달하고 signInWithCustomToken()를 호출하여 사용자를 로그인 처리합니다.

Identity Platform Admin SDK로 커스텀 토큰을 만들거나 타사 JWT 라이브러리를 사용할 수 있습니다.

시작하기 전에

  • Admin SDK를 설치합니다. 서비스 계정 자동 검색 또는 명시적으로 지정된 서비스 계정 ID를 사용하는 경우 사용 중인 서비스 계정에 최소한 서비스 계정 토큰 생성자(roles/iam.serviceAccountTokenCreator) 역할이 있는지 확인합니다.

  • 사용자의 로그인 사용자 인증 정보를 수락하는 서버 엔드포인트를 만들고 배포합니다.

Admin SDK로 커스텀 토큰 만들기

Admin SDK에는 커스텀 토큰을 만드는 메서드가 내장되어 있습니다. 최소한 uid를 제공해야 합니다. 사용자 또는 기기를 고유하게 식별하는 문자열이 될 수 있습니다. 이러한 토큰은 1시간 후에 만료됩니다.

다음 예시에서는 커스텀 토큰을 만드는 방법을 보여줍니다.

Node.js

const uid = 'some-uid';

getAuth()
  .createCustomToken(uid)
  .then((customToken) => {
    // Send token back to client
  })
  .catch((error) => {
    console.log('Error creating custom token:', error);
  });

Java

String uid = "some-uid";

String customToken = FirebaseAuth.getInstance().createCustomToken(uid);
// Send token back to client

Python

uid = 'some-uid'

custom_token = auth.create_custom_token(uid)

Go

client, err := app.Auth(context.Background())
if err != nil {
	log.Fatalf("error getting Auth client: %v\n", err)
}

token, err := client.CustomToken(ctx, "some-uid")
if err != nil {
	log.Fatalf("error minting custom token: %v\n", err)
}

log.Printf("Got custom token: %v\n", token)

C#

var uid = "some-uid";

string customToken = await FirebaseAuth.DefaultInstance.CreateCustomTokenAsync(uid);
// Send token back to client

커스텀 토큰을 만든 후 앱에서 이 토큰을 사용하여 사용자를 로그인 처리할 수 있습니다.

원하는 경우 커스텀 토큰에 대한 추가 클레임을 포함할 수 있습니다. 사용자의 ID 토큰에 최상위 클레임으로 적용됩니다.

다음 예시는 premiumAccount 클레임을 추가하는 방법을 보여줍니다.

Node.js

const userId = 'some-uid';
const additionalClaims = {
  premiumAccount: true,
};

getAuth()
  .createCustomToken(userId, additionalClaims)
  .then((customToken) => {
    // Send token back to client
  })
  .catch((error) => {
    console.log('Error creating custom token:', error);
  });

Java

String uid = "some-uid";
Map<String, Object> additionalClaims = new HashMap<String, Object>();
additionalClaims.put("premiumAccount", true);

String customToken = FirebaseAuth.getInstance()
    .createCustomToken(uid, additionalClaims);
// Send token back to client

Python

uid = 'some-uid'
additional_claims = {
    'premiumAccount': True
}

custom_token = auth.create_custom_token(uid, additional_claims)

Go

client, err := app.Auth(context.Background())
if err != nil {
	log.Fatalf("error getting Auth client: %v\n", err)
}

claims := map[string]interface{}{
	"premiumAccount": true,
}

token, err := client.CustomTokenWithClaims(ctx, "some-uid", claims)
if err != nil {
	log.Fatalf("error minting custom token: %v\n", err)
}

log.Printf("Got custom token: %v\n", token)

C#

var uid = "some-uid";
var additionalClaims = new Dictionary<string, object>()
{
    { "premiumAccount", true },
};

string customToken = await FirebaseAuth.DefaultInstance
    .CreateCustomTokenAsync(uid, additionalClaims);
// Send token back to client

Identity Platform은 OpenID Connect JWT 사양을 준수합니다. 즉, 다음 클레임이 예약되며 지정할 수 없습니다.

  • acr
  • amr
  • at_hash
  • aud
  • auth_time
  • azp
  • cnf
  • c_hash
  • exp
  • firebase
  • iat
  • iss
  • jti
  • nbf
  • nonce
  • sub

타사 JWT 라이브러리로 커스텀 토큰 만들기

백엔드가 Admin SDK가 지원하지 않는 언어로 작성되었더라도 수동으로 커스텀 토큰을 만들 수 있습니다. 우선 해당 언어의 서드 파티 JWT 라이브러리를 검색합니다. 그런 다음 이 라이브러리를 사용하여 다음과 같은 클레임을 포함하는 JWT를 발행합니다.

alg 알고리즘 "RS256"
iss 발급자 프로젝트의 서비스 계정 이메일 주소
sub 제목 프로젝트의 서비스 계정 이메일 주소
aud 대상 "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat 발급 시간 UNIX epoch를 기준으로 하는 현재 시간(초)
exp 만료 시간 Unix epoch를 기준으로 하는 토큰 만료 시간(초). iat보다 최대 3,600초 길어질 수 있습니다.
이 항목은 커스텀 토큰 자체의 만료 시간만 제어합니다. signInWithCustomToken()으로 사용자가 로그인하면 사용자가 로그아웃하거나 세션이 무효화될 때까지 로그인 상태가 유지됩니다.
uid 로그인한 사용자의 고유 식별자(영문 기준 1~36자의 길이의 문자열)
claims(선택사항) 포함할 추가 커스텀 클레임

다음 예시는 Admin SDK가 지원하지 않는 언어로 커스텀 토큰을 만드는 방법을 보여줍니다.

PHP

php-jwt 사용:

// Requires: composer require firebase/php-jwt
use Firebase\JWT\JWT;

// Get your service account's email address and private key from the JSON key file
$service_account_email = "abc-123@a-b-c-123.iam.gserviceaccount.com";
$private_key = "-----BEGIN PRIVATE KEY-----...";

function create_custom_token($uid, $is_premium_account) {
  global $service_account_email, $private_key;

  $now_seconds = time();
  $payload = array(
  "iss" => $service_account_email,
  "sub" => $service_account_email,
  "aud" => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
  "iat" => $now_seconds,
  "exp" => $now_seconds+(60*60),  // Maximum expiration time is one hour
  "uid" => $uid,
  "claims" => array(
      "premium_account" => $is_premium_account
  )
  );
  return JWT::encode($payload, $private_key, "RS256");
}

Ruby

ruby-jwt 사용:

require "jwt"

# Get your service account's email address and private key from the JSON key file
$service_account_email = "service-account@my-project-abc123.iam.gserviceaccount.com"
$private_key = OpenSSL::PKey::RSA.new "-----BEGIN PRIVATE KEY-----\n..."

def create_custom_token(uid, is_premium_account)
  now_seconds = Time.now.to_i
  payload = {:iss => $service_account_email,
              :sub => $service_account_email,
              :aud => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
              :iat => now_seconds,
              :exp => now_seconds+(60*60), # Maximum expiration time is one hour
              :uid => uid,
              :claims => {:premium_account => is_premium_account}}
  JWT.encode payload, $private_key, "RS256"
end

커스텀 토큰을 만든 후 앱에서 이 토큰을 사용하여 사용자를 로그인 처리할 수 있습니다.

다음 단계