Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

Özel Jetonlar Oluşturun

Firebase, güvenli JSON Web Belirteçleri (JWT'ler) kullanarak kullanıcıların veya cihazların kimliğini doğrulamanıza izin vererek kimlik doğrulama üzerinde tam kontrol sağlar. Sen, sunucu üzerinde bu belirteçleri oluşturmak geri bir istemci cihaza geçmek ve daha sonra üzerinden kimlik doğrulaması için kullanabilirsiniz signInWithCustomToken() yöntemiyle.

Bunu başarmak için, kullanıcı adı ve parola gibi oturum açma kimlik bilgilerini kabul eden ve kimlik bilgileri geçerliyse özel bir JWT döndüren bir sunucu uç noktası oluşturmalısınız. Senin sunucusundan döndürülen özel JWT sonra Firebase (kimlik doğrulaması için bir istemci aygıtı tarafından kullanılabilir iOS , Android , web ). Kimliği 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'de içeriği satışa sunulacak auth sizin nesnenin Gerçek Zamanlı Veri Tabanı Kuralları ve request.auth senin nesne Bulut Depolama Güvenliği Kuralları .

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

Sen başlamadan önce

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

  • Bir hizmet hesabı JSON dosyasını kullanarak - Bu yöntem herhangi bir ortamda kullanıldığında, ancak kodu ile birlikte bir hizmet hesabı JSON dosyasını paketlemek gerektirir edilebilir. Hizmet hesabı JSON dosyasının harici taraflara maruz kalmamasını sağlamak için özel dikkat gösterilmelidir.
  • Yönetici SDK hizmet hesabı keşfetmek izin vermek - Bu yöntem, Google Cloud Fonksiyonlar ve App Engine, Google tarafından yönetilen ortamlarda kullanılabilir. Google Cloud Console aracılığıyla bazı ek izinleri yapılandırmanız gerekebilir.
  • Bir hizmet hesabı kimliğini kullanarak - Bir Google tarafından yönetilen bir ortamda kullanıldığında bu yöntem Belirtilen hizmet hesabının tuşunu kullanarak belirteçleri imzalayacak. Ancak, uzak bir web hizmeti kullanır ve bu hizmet hesabı için Google Bulut Konsolu aracılığıyla 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. Takip Yönetici SDK talimatları kurmak bir hizmet hesabı JSON dosyası ile Yönetici SDK'yı başlatmak konusunda daha fazla bilgi için bkz.

Bu başlatma yöntemi, çok çeşitli Yönetici SDK dağıtımları için uygundur. Ayrıca, Yönetici SDK'sı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 tutulması 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.

Yönetici SDK'sının bir hizmet hesabını keşfetmesine izin verme

Kodunuz Google tarafından yönetilen bir ortamda dağıtılmışsa, Yönetici SDK'sı özel belirteçleri imzalamak için bir yolu otomatik olarak keşfetmeyi deneyebilir:

  • Kodunuzu Java Python veya Go App Engine standart ortamda dağıtılırsa, Yönetici SDK kullanabilirsiniz App Kimlik servis özel belirteçleri imzalamak için bu ortamda mevcut. App Identity hizmeti, Google App Engine tarafından uygulamanız için sağlanan bir hizmet hesabını kullanarak verileri imzalar.

  • Kodunuzu diğer yönetilen bir ortamda (örneğin, Google Cloud Fonksiyonlar Google Bilişim Altyapısı) dağıtılmışsa Firebase Yönetici SDK kutu yerel bir hizmet hesabı kimlik dizesi otomatik keşfetmek meta sunucusu . 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 Application Default kimlik bilgileriyle başlatın ve bir hizmet hesabı kimliği dizesi belirtmeyin:

Node.js

initializeApp();

Java

FirebaseApp.initializeApp();

piton

default_app = firebase_admin.initialize_app()

Gitmek

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

C#

FirebaseApp.Create();

Yerel olarak aynı kodu test etmek için, bir hizmet hesabı JSON dosyasını indirmek ve set GOOGLE_APPLICATION_CREDENTIALS buna noktaya ortam değişkeni.

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

Sadece açıkça belirtilen hizmet hesabı kimlikleri olduğu gibi, oto-discoverd hizmet hesap kimlikleri olmalıdır iam.serviceAccounts.signBlob işe özel işaret oluşturmaya yönelik iznini. Sen kullanmanız gerekebilir IAM ve yönetici varsayılan hizmet gerekli izinleri hesapları vermek için Google Bulut Konsolu bölümüne. 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ığı korumak için, anahtarları Google tarafından yönetilen bir ortamda çalışırken belirteçleri 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 dahil etmekten kaçınabilir.

Hizmet hesabı kimliği bulunabilir Google Cloud Console veya içinde client_email indirilmiş bir hizmet hesabı JSON dosyasına alanında. Servis hesap kimliği şu biçime sahip e-posta adresleri şunlardır: <client-id>@<project-id>.iam.gserviceaccount.com . Firebase ve Google Cloud projelerinde hizmet hesaplarını benzersiz bir ş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

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

Java

FirebaseOptions options = 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)

Gitmek

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 maruz kalmaları önemsizdir. Ancak, belirtilen hizmet hesabıyla özel belirteçleri imzalamak için Firebase Admin SDK'sı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'sını kullanarak özel jetonlar oluşturun

Firebase Admin SDK, özel belirteçler 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 bir saat sonra sona erer.

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

piton

uid = 'some-uid'

custom_token = auth.create_custom_token(uid)

Gitmek

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

İsteğe bağlı olarak, özel belirteçte eklenecek ek talepleri de belirtebilirsiniz. Örneğin, aşağıda, bir premiumAccount alan satışa sunulacak özel belirteci, eklendi auth / request.auth Güvenlik Kuralları nesnelerin:

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

piton

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

custom_token = auth.create_custom_token(uid, additional_claims)

Gitmek

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 belirteç oluşturduktan sonra bunu istemci uygulamanıza göndermelisiniz. Arayarak belirteci özel istemci uygulaması kimlik doğrulamasını signInWithCustomToken() :

iOS

Amaç-C
[[FIRAuth auth] signInWithCustomToken:customToken
                           completion:^(FIRAuthDataResult * _Nullable authResult,
                                        NSError * _Nullable error) {
  // ...
}];
Süratli
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)
  .then((userCredential) => {
    // Signed in
    var user = userCredential.user;
    // ...
  })
  .catch((error) => {
    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.

Oturum açma yöntemlerinin (örneğin diğer aynı şekilde signInWithEmailAndPassword() ve signInWithCredential() ) auth sizin nesne Gerçek Zamanlı Veri Tabanı Kuralları ve request.auth senin nesne Bulut Depolama Güvenliği Kuralları kullanıcının doldurulur uid . Bu durumda, uid özel bir kod oluşturduktan belirttiğiniz o biri olacak.

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 belirteci ilave iddialar içeriyorsa, kapalı başvurulabilir auth.token (Firebase Gerçek Zamanlı Veri Tabanı) ya da request.auth.token Kurallarınızda (Bulut Depolama) nesnesi:

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 JWT kitaplığı kullanarak özel belirteçler oluşturun

Arka ucunuz resmi bir Firebase Admin SDK'sı olmayan bir dildeyse, yine de manuel olarak özel belirteçler oluşturabilirsiniz. İlk olarak, bir üçüncü taraf JWT kütüphanesini bulmak Diliniz için. Ardından, aşağıdaki iddiaları içeren bir JWT'yi basmak için bu JWT kitaplığını kullanın:

Özel Jeton Talepleri
alg algoritma "RS256"
iss ihraççı Projenizin hizmet hesabı e-posta adresi
sub Ders Projenizin hizmet hesabı e-posta adresi
aud Kitle "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat Yayınlandığı tarihte UNIX döneminden bu yana saniye cinsinden geçerli zaman
exp son kullanma süresi Belirtecin sona erdiği UNIX döneminden bu yana saniye cinsinden süre. Daha sonra daha 3600 saniye uzunluğunda olabilir iat .
Not: kendisi belirteç özel süresi dolduğunda bu sadece zaman kontrol eder. Ama senin bir kez kullanarak bir kullanıcı oturum signInWithCustomToken() , oturum geçersiz kılınan veya kullanıcı çıkış kadar, bunlar cihazın içine imzalanan kalacaktı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ı) İsteğe bağlı özel talepler Güvenlik Kuralları dahil etmek auth / request.auth değişkenleri

Firebase Admin SDK'nın desteklemediği çeşitli dillerde özel belirteçlerin nasıl oluşturulacağına ilişkin bazı örnek uygulamaları burada bulabilirsiniz:

PHP

Kullanılması 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");
}

yakut

Kullanılması 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

Özel belirteci oluşturduktan sonra, Firebase ile kimlik doğrulaması yapmak için kullanmak üzere istemci uygulamanıza gönderin. Bunun nasıl yapılacağı 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 Yönetici SDK kullanan IAM API işaret jeton için. Bu hata, IAM API'sinin şu anda Firebase projeniz için etkinleştirilmediğini 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

Servis Firebase Yönetici SDK olmadığı için çalıştığı kullanıcı hesabı varsa iam.serviceAccounts.signBlob izni, aşağıdakilerden gibi 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 çözmek için en kolay yolu, söz konusu hizmet hesabına "Hizmet Hesabı Jetonu Creator" IAM rolü verilmesi için ise, genellikle {project-name}@appspot.gserviceaccount.com :

  1. IAM ve yönetici Google Bulut Konsolu'nda sayfa.
  2. Projenizi seçin ve "Devam"a tıklayın.
  3. Güncellemek istediğiniz hizmet hesabına karşılık gelen düzenle simgesini tıklayın.
  4. "Başka Bir Rol Ekle" ye tıklayın.
  5. Arama filtresine "Service Account Token Creator" yazın ve sonuçlardan seçin.
  6. Rol tahsisini onaylamak için "Kaydet"i tıklayın.

Bakınız IAM belgelerinde Bu işlemle ilgili daha fazla ayrıntı için, ya gcloud komut satırı araçlarını kullanarak güncelleme rollerini nasıl yapılacağını öğrenmek.

Hizmet hesabı belirlenemedi

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

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 bulmak 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şlatmada hizmet hesabı JSON dosyasını veya hizmet hesabı kimliğini belirttiğinizden emin olun.