Google is committed to advancing racial equity for Black communities. See how.
Bu sayfa, Cloud Translation API ile çevrilmiştir.
Switch to English

Özel Jeton Oluşturun

Firebase, güvenli JSON Web Jetonları (JWT'ler) kullanarak kullanıcıların veya cihazların kimliğini doğrulamanıza olanak tanıyarak kimlik doğrulaması üzerinde tam kontrol sağlar. Bu belirteçleri sunucunuzda oluşturursunuz, bir istemci cihaza geri gönderirsiniz ve ardından signInWithCustomToken() yöntemi aracılığıyla kimlik doğrulaması yapmak için signInWithCustomToken() .

Bunu başarmak için, kullanıcı adı ve şifre gibi oturum açma kimlik bilgilerini kabul eden ve kimlik bilgileri geçerliyse özel bir JWT döndüren bir sunucu uç noktası oluşturmanız gerekir. Sunucunuzdan döndürülen özel JWT, daha sonra bir istemci cihaz tarafından Firebase ( iOS , Android , web ) ile kimlik doğrulaması yapmak için kullanılabilir. Kimlik doğrulandıktan sonra bu kimlik, Firebase Realtime Database ve Cloud Storage gibi diğer Firebase hizmetlerine erişilirken kullanılacaktır. Ayrıca JWT'nin içeriği, Firebase Gerçek Zamanlı Veritabanı Güvenlik Kurallarınızdaki auth nesnesinde ve Cloud Storage Güvenlik Kurallarınızdaki request.auth nesnesinde mevcut olacaktır.

Firebase Admin SDK ile özel bir jeton oluşturabilir veya sunucunuz Firebase'in yerel olarak desteklemediği bir dilde yazıldıysa üçüncü taraf bir JWT kitaplığı kullanabilirsiniz.

Sen başlamadan önce

Özel belirteçler, imzalamak için kullanılan özel anahtarın bir Google hizmet hesabına ait olduğu imzalı JWT'lerdir. Firebase Admin SDK tarafından özel jetonları imzalamak için kullanılması gereken Google hizmet hesabını belirlemenin birkaç yolu vardır:

  • Bir hizmet hesabı JSON dosyası kullanma - Bu yöntem herhangi bir ortamda kullanılabilir, ancak kodunuzla birlikte bir hizmet hesabı JSON dosyasını paketlemenizi gerektirir. Hizmet hesabı JSON dosyasının harici taraflara açık olmamasını sağlamak için özel dikkat gösterilmelidir.
  • Admin SDK'nın bir hizmet hesabı keşfetmesine izin verme - Bu yöntem, Google Cloud Functions ve Google App Engine gibi Google tarafından yönetilen ortamlarda kullanılabilir. Google Cloud Platform konsolu aracılığıyla bazı ek izinleri yapılandırmanız gerekebilir.
  • Bir hizmet hesabı kimliği kullanma - Google tarafından yönetilen bir ortamda kullanıldığında, bu yöntem belirteçleri belirtilen hizmet hesabının anahtarını kullanarak imzalar. Ancak, uzak bir web hizmeti kullanır ve Google Cloud Platform konsolu aracılığıyla bu hizmet hesabı için ek izinler yapılandırmanız gerekebilir.

Bir hizmet hesabı JSON dosyası kullanma

Hizmet hesabı JSON dosyaları, hizmet hesaplarına karşılık gelen tüm bilgileri içerir (RSA özel anahtarı dahil). Firebase Konsolundan indirilebilirler. Admin SDK'nın bir hizmet hesabı JSON dosyasıyla nasıl başlatılacağı hakkında daha fazla bilgi için Admin SDK kurulum talimatlarını uygulayın .

Bu başlatma yöntemi, çok çeşitli Yönetici SDK dağıtımları için uygundur. Ayrıca, Admin SDK'nın herhangi bir uzak API çağrısı yapmadan yerel olarak özel belirteçler oluşturmasını ve imzalamasını sağlar. Bu yaklaşımın ana dezavantajı, kodunuzla birlikte bir hizmet hesabı JSON dosyasını paketlemenizi gerektirmesidir. Ayrıca, bir hizmet hesabı JSON dosyasındaki özel anahtarın hassas bilgiler olduğunu ve gizli tutmak için özel dikkat gösterilmesi gerektiğini unutmayın. Özellikle, hizmet hesabı JSON dosyalarını genel sürüm denetimine eklemekten kaçının.

Admin SDK'nın bir hizmet hesabı bulmasına izin verme

Kodunuz Google tarafından yönetilen bir ortama yerleştirildiyse, Yönetici SDK'si özel jetonları imzalamanın bir yolunu otomatik olarak keşfetmeyi deneyebilir:

  • Kodunuz Java, Python veya Go için Google App Engine standart ortamında dağıtılmışsa, Yönetici SDK'sı, özel jetonları imzalamak için bu ortamda bulunan Uygulama Kimliği hizmetini kullanabilir. Uygulama Kimliği hizmeti, uygulamanız için Google App Engine tarafından sağlanan bir hizmet hesabını kullanarak verileri imzalar.

  • Kodunuz başka bir yönetilen ortamda (ör. Google Cloud Functions, Google Compute Engine) dağıtılırsa Firebase Admin SDK, yerel meta veri sunucusundan bir hizmet hesabı kimliği dizesini otomatik olarak keşfedebilir. Keşfedilen hizmet hesabı kimliği daha sonra belirteçleri uzaktan imzalamak için IAM hizmetiyle birlikte kullanılır.

Bu imzalama yöntemlerinden yararlanmak için, SDK'yı Google Uygulama Varsayılanı kimlik bilgileriyle başlatın ve bir hizmet hesabı kimliği dizesi belirtmeyin:

node.js

 admin.initializeApp();
 

Java

 FirebaseApp.initializeApp();
 

piton

 default_app = firebase_admin.initialize_app()
 

Git

 app, err := firebase.NewApp(context.Background(), nil)
if err != nil {
	log.Fatalf("error initializing app: %v\n", err)
} 

C #

 FirebaseApp.Create();
 

Aynı kodu yerel olarak test etmek için bir hizmet hesabı JSON dosyası indirin ve GOOGLE_APPLICATION_CREDENTIALS ortam değişkenini onu gösterecek şekilde ayarlayın.

Firebase Admin SDK'nın bir hizmet hesabı kimliği dizesi bulması gerekiyorsa, bunu kodunuz ilk kez özel bir jeton oluşturduğunda yapar. Sonuç, önbelleğe alınır ve sonraki simge imzalama işlemleri için yeniden kullanılır. Otomatik keşfedilen hizmet hesabı kimliği, genellikle Google Cloud Platform tarafından sağlanan varsayılan hizmet hesaplarından biridir:

Açıkça belirtilen hizmet hesabı kimliklerinde olduğu gibi, özel simge oluşturmanın çalışması için otomatik keşfedilen hizmet hesabı kimliklerinin iam.serviceAccounts.signBlob iznine sahip olması gerekir. Varsayılan hizmet hesaplarına gerekli izinleri vermek için Google Cloud Platform Konsolu'nun IAM ve yönetici bölümünü kullanmanız gerekebilir. Daha fazla ayrıntı için aşağıdaki sorun giderme bölümüne bakın.

Hizmet hesabı kimliği kullanma

Uygulamanızın çeşitli bölümleri arasında tutarlılığı sağlamak için, anahtarları Google tarafından yönetilen bir ortamda çalışırken jetonları imzalamak için kullanılacak bir hizmet hesabı kimliği belirtebilirsiniz. Bu, IAM politikalarını daha basit ve daha güvenli hale getirebilir ve hizmet hesabı JSON dosyasını kodunuza eklemek zorunda kalmazsınız.

Hizmet hesabı kimliği, Google Cloud Platform konsolunda veya indirilen bir hizmet hesabı JSON dosyasının client_email alanında bulunabilir. Hizmet hesabı kimlikleri, şu biçime sahip e-posta adresleridir: <client-id>@<project-id>.iam.gserviceaccount.com . Firebase ve Google Cloud Platform projelerinde hizmet hesaplarını benzersiz şekilde tanımlarlar.

Ayrı bir hizmet hesabı kimliği kullanarak özel belirteçler oluşturmak için, SDK'yı aşağıda gösterildiği gibi başlatın:

node.js

 admin.initializeApp({
  serviceAccountId: 'my-client-id@my-project-id.iam.gserviceaccount.com',
});
 

Java

 FirebaseOptions options = new FirebaseOptions.Builder()
    .setCredentials(GoogleCredentials.getApplicationDefault())
    .setServiceAccountId("my-client-id@my-project-id.iam.gserviceaccount.com")
    .build();
FirebaseApp.initializeApp(options);
 

piton

 options = {
    'serviceAccountId': 'my-client-id@my-project-id.iam.gserviceaccount.com',
}
firebase_admin.initialize_app(options=options)
 

Git

 conf := &firebase.Config{
	ServiceAccountID: "my-client-id@my-project-id.iam.gserviceaccount.com",
}
app, err := firebase.NewApp(context.Background(), conf)
if err != nil {
	log.Fatalf("error initializing app: %v\n", err)
} 

C #

 FirebaseApp.Create(new AppOptions()
{
    Credential = GoogleCredential.GetApplicationDefault(),
    ServiceAccountId = "my-client-id@my-project-id.iam.gserviceaccount.com",
});
 

Hizmet hesabı kimlikleri hassas bilgiler değildir ve bu nedenle ifşaları önemsizdir. Ancak, belirtilen hizmet hesabıyla özel jetonları imzalamak için Firebase Admin SDK'nın bir uzak hizmeti çağırması gerekir. Ayrıca, aynı zamanda hizmet Yönetici SDK bu çağrıyı -genellikle yapmak için kullandığı hesabı emin olmalısınız {project-name}@appspot.gserviceaccount.com - sahiptir iam.serviceAccounts.signBlob izni . Daha fazla ayrıntı için aşağıdaki sorun giderme bölümüne bakın.

Firebase Admin SDK'yı kullanarak özel jetonlar oluşturun

Firebase Admin SDK, özel jetonlar oluşturmak için yerleşik bir yönteme sahiptir. En azından, bir sağlamanız gerekir uid herhangi bir dize olabilir ama benzersiz olarak kimlik doğrulaması yapılırken kullanıcı veya cihazı tanımlamak gerekir. Bu jetonların süresi bir saat sonra dolar.

node.js

 let uid = 'some-uid';

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

Java

 String uid = "some-uid";

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

piton

 uid = 'some-uid'

custom_token = auth.create_custom_token(uid) 

Git

 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
 

Ayrıca isteğe bağlı olarak özel jetona dahil edilecek ek talepler de belirtebilirsiniz. Örneğin, aşağıda, Güvenlik Kurallarınızdaki auth / request.auth nesnelerinde bulunabilecek özel premiumAccount bir premiumAccount alanı eklenmiştir:

node.js

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

admin.auth().createCustomToken(userId, additionalClaims)
  .then(function(customToken) {
    // Send token back to client
  })
  .catch(function(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
 

piton

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

custom_token = auth.create_custom_token(uid, additional_claims) 

Git

 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
 

İstemcilerde özel belirteçler kullanarak oturum açın

Özel bir jeton oluşturduktan sonra, bunu istemci uygulamanıza göndermelisiniz. İstemci uygulaması, signInWithCustomToken() çağırarak özel belirteçle kimlik doğrulaması signInWithCustomToken() :

iOS

Objective-C
 [[FIRAuth auth] signInWithCustomToken:customToken
                           completion:^(FIRAuthDataResult * _Nullable authResult,
                                        NSError * _Nullable error) {
  // ...
}];
 
hızlı
 Auth.auth().signIn(withCustomToken: customToken ?? "") { (user, error) in
  // ...
}
 

Android

 mAuth.signInWithCustomToken(mCustomToken)
        .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    // Sign in success, update UI with the signed-in user's information
                    Log.d(TAG, "signInWithCustomToken:success");
                    FirebaseUser user = mAuth.getCurrentUser();
                    updateUI(user);
                } else {
                    // If sign in fails, display a message to the user.
                    Log.w(TAG, "signInWithCustomToken:failure", task.getException());
                    Toast.makeText(CustomAuthActivity.this, "Authentication failed.",
                            Toast.LENGTH_SHORT).show();
                    updateUI(null);
                }
            }
        });
 

Birlik

 auth.SignInWithCustomTokenAsync(custom_token).ContinueWith(task => {
  if (task.IsCanceled) {
    Debug.LogError("SignInWithCustomTokenAsync was canceled.");
    return;
  }
  if (task.IsFaulted) {
    Debug.LogError("SignInWithCustomTokenAsync encountered an error: " + task.Exception);
    return;
  }

  Firebase.Auth.FirebaseUser newUser = task.Result;
  Debug.LogFormat("User signed in successfully: {0} ({1})",
      newUser.DisplayName, newUser.UserId);
});
 

C ++

 firebase::Future<firebase::auth::User*> result =
    auth->SignInWithCustomToken(custom_token);
 

 firebase.auth().signInWithCustomToken(token).catch(function(error) {
  // Handle Errors here.
  var errorCode = error.code;
  var errorMessage = error.message;
  // ...
});
 

Kimlik doğrulama başarılı olursa, kullanıcı artık tarafından belirtilen hesabı ile istemci uygulamasına imzalanacak uid özel belirteci dahil. Bu hesap daha önce mevcut değilse, o kullanıcı için bir kayıt oluşturulacaktır.

Diğer oturum açma yöntemlerinde ( signInWithEmailAndPassword() ve signInWithCredential() gibi) olduğu gibi, signInWithEmailAndPassword() Gerçek Zamanlı Veritabanı Güvenlik Kurallarınızdaki auth nesnesi ve Bulut Depolama Güvenlik Kurallarınızdaki request.auth nesnesi, kullanıcının uid . Bu durumda, uid , özel belirteci oluştururken belirttiğiniz uid olacaktır.

Veritabanı Kuralları

 {
  "rules": {
    "adminContent": {
      ".read": "auth.uid === 'some-uid'"
    }
  }
}
 

Depolama Kuralları

 service firebase.storage {
  match /b/<your-firebase-storage-bucket>/o {
    match /adminContent/{filename} {
      allow read, write: if request.auth != null && request.auth.uid == "some-uid";
    }
  }
}
 

Özel jeton ek talepler içeriyorsa, auth.token ( auth.token Realtime Database) veya request.auth.token (Cloud Storage) nesnesi üzerinden auth.token referans auth.token :

Veritabanı Kuralları

 {
  "rules": {
    "premiumContent": {
      ".read": "auth.token.premiumAccount === true"
    }
  }
}
 

Depolama Kuralları

 service firebase.storage {
  match /b/<your-firebase-storage-bucket>/o {
    match /premiumContent/{filename} {
      allow read, write: if request.auth.token.premiumAccount == true;
    }
  }
}
 

Üçüncü taraf bir JWT kitaplığı kullanarak özel belirteçler oluşturun

Arka ucunuz resmi bir Firebase Admin SDK'sı olmayan bir dildeyse, yine de manuel olarak özel jetonlar oluşturabilirsiniz. Öncelikle, diliniz için üçüncü taraf bir JWT kitaplığı bulun. Ardından, aşağıdaki iddiaları içeren bir JWT yazdırmak için bu JWT kitaplığını kullanın:

Özel Jeton Hak Talepleri
alg Algoritma "RS256"
iss İhraççı Projenizin hizmet hesabı e-posta adresi
sub konu Projenizin hizmet hesabı e-posta adresi
aud seyirci "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat Verildiği zaman UNIX döneminden bu yana saniye cinsinden geçerli saat
exp Son kullanma süresi Belirtecin süresinin dolduğu UNIX döneminden bu yana saniye cinsinden süre. iat maksimum 3600 saniye geç olabilir .
Not: Bu yalnızca özel jetonun süresinin dolacağı zamanı kontrol eder. Ancak, signInWithCustomToken() kullanarak bir kullanıcı oturum açtığınızda, oturumu geçersiz signInWithCustomToken() veya kullanıcı oturumu kapatana kadar aygıtta oturum signInWithCustomToken() durumda kalır.
uid Oturum açan kullanıcının benzersiz tanımlayıcısı 1-36 karakter uzunluğunda bir dize olmalıdır
claims (isteğe bağlı) Güvenlik Kuralları auth / request.auth değişkenlerine dahil edilecek isteğe bağlı özel talepler

Firebase Admin SDK'nın desteklemediği çeşitli dillerde özel jetonların nasıl oluşturulacağına ilişkin bazı örnek uygulamalar şunlardır:

PHP

php-jwt kullanarak:

 // 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");
}
 

yakut

ruby-jwt kullanarak:

 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
 

Özel jetonu oluşturduktan sonra, Firebase ile kimlik doğrulaması yapmak için kullanmak üzere istemci uygulamanıza gönderin. Bunun nasıl yapılacağını öğrenmek için yukarıdaki kod örneklerine bakın.

Sorun giderme

Bu bölüm, geliştiricilerin özel belirteçler oluştururken karşılaşabilecekleri bazı genel sorunları ve bunların nasıl çözüleceğini özetlemektedir.

IAM API etkinleştirilmedi

Belirteçleri imzalamak için bir hizmet hesabı kimliği belirtiyorsanız, aşağıdakine benzer bir hata alabilirsiniz:

Identity and Access Management (IAM) API has not been used in project
1234567890 before or it is disabled. Enable it by visiting
https://console.developers.google.com/apis/api/iam.googleapis.com/overview?project=1234567890
then retry. If you enabled this API recently, wait a few minutes for the action
to propagate to our systems and retry.

Firebase Admin SDK, jetonları imzalamak için IAM API'yi kullanır. Bu hata, IAM API'nin şu anda Firebase projeniz için etkin olmadığını gösterir. Hata mesajındaki bağlantıyı bir web tarayıcısında açın ve projeniz için etkinleştirmek üzere "API'yi Etkinleştir" düğmesini tıklayın.

Hizmet hesabının gerekli izinleri yok

Firebase Admin SDK hizmet hesabı iam.serviceAccounts.signBlob iznine sahip olmadığı için çalışıyorsa aşağıdakine benzer bir hata mesajı alabilirsiniz:

Permission iam.serviceAccounts.signBlob is required to perform this operation
on service account projects/-/serviceAccounts/{your-service-account-id}.

Bu sorunu çözmenin en kolay yolu, söz konusu hizmet hesabına genellikle {project-name}@appspot.gserviceaccount.com üzere "Service Account Token Creator" IAM rolünü {project-name}@appspot.gserviceaccount.com :

  1. Google Cloud Platform Console'da IAM ve yönetici sayfasını açın.
  2. Projenizi seçin ve "Devam Et" e tıklayın.
  3. Güncellemek istediğiniz hizmet hesabına karşılık gelen düzenle simgesine tıklayın.
  4. "Başka Bir Rol Ekle" ye tıklayın.
  5. Arama filtresine "Service Account Token Creator" yazın ve sonuçlar arasından seçin.
  6. Rol verilmesini onaylamak için "Kaydet" i tıklayın.

Bu işlemle ilgili daha fazla ayrıntı için IAM belgelerine bakın veya gcloud komut satırı araçlarını kullanarak güncelleme rollerini nasıl yapacağınızı öğrenin.

Hizmet hesabı belirlenemedi

Aşağıdakine benzer bir hata mesajı alırsanız Firebase Admin SDK düzgün şekilde başlatılmamıştır.

Failed to determine service account ID. Initialize the SDK with service account
credentials or specify a service account ID with iam.serviceAccounts.signBlob
permission.

Bir hizmet hesabı kimliğini otomatik olarak keşfetmek için SDK'ya güveniyorsanız, kodun bir meta veri sunucusuyla yönetilen bir Google ortamında dağıtıldığından emin olun. Aksi takdirde, SDK başlatılırken hizmet hesabı JSON dosyasını veya hizmet hesabı kimliğini belirttiğinizden emin olun.