יצירת טוקנים בהתאמה אישית

במאמר הזה מוסבר איך להשתמש ב-Identity Platform כדי ליצור אסימוני JWT (‏JSON Web Tokens) בהתאמה אישית.

אסימונים בהתאמה אישית מאפשרים לכם שליטה מלאה בתהליך האימות. אתם יוצרים את האסימונים האלה בשרת, מעבירים אותם בחזרה למכשיר לקוח ואז קוראים ל-signInWithCustomToken() כדי שהמשתמשים יוכלו להיכנס.

אפשר ליצור טוקנים בהתאמה אישית באמצעות Identity Platform SDK לאדמינים, או להשתמש בספריית JWT של צד שלישי.

לפני שמתחילים

  • מתקינים את SDK לאדמינים. אם אתם משתמשים בגילוי אוטומטי של חשבון שירות או במזהה חשבון שירות שצוין באופן מפורש, ודאו שלחשבון השירות שבו אתם משתמשים יש לפחות את התפקיד 'יצירת אסימונים בחשבון שירות' (roles/iam.serviceAccountTokenCreator).

  • יוצרים ופורסים נקודת קצה של שרת שמקבלת פרטי כניסה ממשתמשים.

יצירת טוקנים בהתאמה אישית באמצעות SDK לאדמינים

ל-SDK לאדמינים יש שיטה מובנית ליצירת טוקנים בהתאמה אישית. לפחות צריך לספק uid. המזהה יכול להיות כל מחרוזת שמזהה באופן ייחודי את המשתמש או המכשיר. התוקף של האסימונים האלה פג אחרי שעה אחת.

בדוגמה הבאה מוצג אופן היצירה של אסימון בהתאמה אישית:

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

אחרי שיוצרים טוקן בהתאמה אישית, האפליקציה יכולה להשתמש בו כדי להיכנס לחשבון של משתמש.

אפשר גם לכלול טענות נוספות באסימון המותאם אישית. הם מועברים לאסימון המזהה של המשתמש כטענות ברמה העליונה.

בדוגמה הבאה אפשר לראות איך מוסיפים הצהרת זכויות יוצרים מסוג 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 תואמת למפרט של JWT ב-OpenID Connect. המשמעות היא שהתלונות הבאות שמורות ואי אפשר לציין אותן:

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

יצירת אסימונים בהתאמה אישית באמצעות ספריית JWT של צד שלישי

אם הבק-אנד כתוב בשפה ש-SDK לאדמינים לא תומך בה, עדיין אפשר ליצור באופן ידני טוקנים בהתאמה אישית. קודם, מחפשים ספריית JWT של צד שלישי בשפה שלכם. לאחר מכן, משתמשים בספרייה הזו כדי ליצור אסימון JWT שכולל את ההצהרות הבאות:

alg אלגוריתם "RS256"
iss מנפיק כתובת האימייל בחשבון השירות של הפרויקט.
sub נושא כתובת האימייל בחשבון השירות של הפרויקט.
aud קהל "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat השעה שבה הונפק הזמן הנוכחי, בשניות, מאז ראשית זמן יוניקס (Unix epoch).
exp שעת התפוגה הזמן שבו יפוג תוקף האסימון, בשניות מאז ראשית זמן יוניקס (Unix epoch). התאריך יכול להיות עד 3,600 שניות אחרי התאריך iat.
חשוב לציין שההגדרה הזו קובעת רק את הזמן שבו יפוג התוקף של האסימון המותאם אישית עצמו. אחרי שמחברים משתמש באמצעות signInWithCustomToken(), הוא נשאר מחובר עד שהוא מתנתק או עד שהסשן שלו הופך ללא תקף.
uid המזהה הייחודי של המשתמש שמחובר לחשבון. הערך חייב להיות מחרוזת באורך של 1 עד 36 תווים.
claims (אופציונלי) תביעות נוספות בהתאמה אישית שרוצים לכלול.

בדוגמאות הבאות מוסבר איך ליצור אסימונים בהתאמה אישית בשפות ש-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

אחרי שיוצרים אסימון בהתאמה אישית, האפליקציה יכולה להשתמש בו כדי להיכנס לחשבון של משתמש.

המאמרים הבאים