カスタム トークンの作成

このドキュメントでは、Identity Platform を使用してカスタムの JSON Web Token(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 エポック時刻からの秒数)
exp 有効期限 トークンの有効期限が切れる時間(UNIX エポック時刻からの秒数)。iat から最大 3,600 秒後の時間を設定できます。
ただし、これは、カスタム トークン自体の有効期限が切れる時間のみを制御できます。signInWithCustomToken() でログインしたユーザーは、ログアウトするかセッションが無効になるまでログインしたままになります。
uid ログイン済みユーザーの一意の ID(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

カスタム トークンを作成すると、アプリではそれをユーザーのログインに使用できます。

次のステップ