Firebase, aşağıdakileri yaparak kimlik doğrulama üzerinde tam kontrol sağlar:
Güvenli JSON Web Jetonları (JWT'ler) kullanarak kullanıcıların veya cihazların kimliğini doğrulama. Sizin oluşturduğunuz
sunucu üzerinde kontrol edip bir istemci cihazına geri iletmeli ve daha sonra
bu kullanıcıların kimliklerini signInWithCustomToken()
yöntemiyle doğrulamalarını öneririz.
Bunu yapmak için, oturum açma kimlik bilgilerini (ör. kullanıcı adı ve şifre) 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, istemci cihaz tarafından Firebase ile kimlik doğrulama yapmak için kullanılabilir (iOS+, Android, web). Kimlik doğrulaması yapılan bu kimlik, Firebase Realtime Database ve Cloud Storage gibi diğer Firebase hizmetlerine erişirken kullanılır. Ayrıca, JWT'nin içeriği Realtime Database Security Rules dizininizdeki auth
nesnesinde ve Cloud Storage Security Rules dizininizdeki request.auth
nesnesinde kullanılabilir.
Firebase Admin SDK ile özel jeton oluşturabilir veya Sunucunuz şu dilde yazılmışsa üçüncü taraf bir JWT kitaplığını kullanabilirsiniz: Firebase'in yerel olarak desteklemediği bir dil.
Başlamadan önce
Özel jetonlar, imzalama için kullanılan özel anahtarın ait olduğu imzalı JWT'lerdir. bir Google hizmet hesabı oluşturun. Firebase Admin SDK'sının özel jetonları imzalamak için kullanması gereken Google hizmet hesabını belirtmenin birkaç yolu vardır:
- Hizmet hesabı JSON dosyası kullanma: Bu yöntem her ortamda kullanılabilir ancak kodunuzla birlikte bir hizmet hesabı JSON dosyası paketlemenizi gerektirir. hizmet hesabı JSON dosyası harici taraflara sunulmaz.
- Yönetici SDK'sının bir hizmet hesabını bulmasına izin verme -- Bu yöntem Google Cloud gibi Google tarafından yönetilen ortamlarda kullanılabilir İşlevler ve App Engine. Bazı görevleri ve Google Cloud konsolu üzerinden ek izinler verebilirsiniz.
- Hizmet hesabı kimliği kullanma: Google tarafından yönetilen bir ortamda kullanıldığında bu yöntem, belirtilen hizmet hesabının anahtarını kullanarak jetonları imzalar. Ancak uzaktan web hizmetini kullanır ve bu nedenle bu hizmet hesabı için ek izinler: Google Cloud konsolu.
Hizmet hesabı JSON dosyası kullanma
Hizmet hesabı JSON dosyaları, hizmet hesaplarına karşılık gelen tüm bilgileri (RSA özel anahtarı dahil) içerir. Buradan indirilebilirler: Firebase konsolu. Yönetici SDK'sı kurulumunu uygulayın. daha fazla bilgi için Yönetici SDK'sını bir hizmet hesabı JSON dosyasıyla başlatın.
Bu başlatma yöntemi, çok çeşitli Admin SDK dağıtımları için uygundur. Ayrıca Admin SDK'nın özel jetonlar oluşturmasını ve imzalamasını sağlar herhangi bir uzak API çağrısı yapmadan yerel olarak. Bunun temel dezavantajı, bir hizmet hesabı JSON dosyası paketlemenizi gerektirmesidir. kodunuza ekler. Ayrıca, bir hizmet hesabındaki özel anahtarın JSON dosyası hassas bilgiler içerdiğinden, bunların kabul etmesini sağlar. Özellikle, hizmet hesabı JSON dosyalarını herkese açık sürüm kontrolüne eklemekten kaçının.
Admin SDK'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 jetonları imzalamanın bir yolunu otomatik olarak keşfetmeye çalışabilir:
Kodunuz Java, Python veya Go için 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, Google App Engine tarafından uygulamanız için temel hazırlığı yapılan bir hizmet hesabını kullanarak verileri imzalar.
Kodunuz Google Cloud gibi başka bir yönetilen ortamda dağıtıldıysa İşlevleri, Google Compute Engine), Firebase Admin SDK'sı kullanıcı aracısına otomatik olarak bir yerel dildeki hizmet hesabı kimliği dizesi meta veri sunucusuyla uyumludur. Keşfedilen hizmet hesabı kimliği daha sonra IAM ile birlikte kullanılır. hizmeti sunar.
Bu imzalama yöntemlerinden yararlanmak için SDK'yı Google ile başlatın Uygulama Varsayılan kimlik bilgileri ve hizmet hesabı kimliği dizesi belirtmeyin:
Node.js
initializeApp();
Java
FirebaseApp.initializeApp();
Python
default_app = firebase_admin.initialize_app()
Go
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şkeni ekleyin.
Firebase Admin SDK'nın bir hizmet hesabı kimliği dizesi keşfetmesi gerektiğinde yeni bir kod eklemenizi öneririz. Sonuç önbelleğe alınır ve sonraki jeton 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:
Açıkça belirtilen hizmet hesabı kimliklerinde olduğu gibi, özel jeton oluşturmanın çalışması için otomatik olarak keşfedilen hizmet hesabı kimliklerinde de iam.serviceAccounts.signBlob
izni olmalıdır. Bunun için
IAM ve yönetici bölümü
Google Cloud konsolunun varsayılan hizmet hesaplarına
gerekli izinleri verebilirsiniz. Daha fazla bilgi 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 şunları yapabilirsiniz: çalışırken jetonları imzalamak için anahtarları kullanılacak bir hizmet hesabı kimliği belirtin Google tarafından yönetilen bir ortamda saklanır. Bu, IAM politikalarını daha basit ve daha güvenli hale getirebilir ve hizmet hesabı JSON dosyasını kodunuza eklemenizi önleyebilir.
Hizmet hesabı kimliği şurada bulunabilir:
Google Cloud konsolu,
veya indirilen bir hizmet hesabı JSON dosyasının client_email
alanında kullanılabilir.
Hizmet hesabı kimlikleri, aşağıdaki biçimde olan e-posta adresleridir:
<client-id>@<project-id>.iam.gserviceaccount.com
Benzersiz bir şekilde
Firebase'deki ve Google Cloud projelerindeki hizmet hesaplarında kullanılabilir.
Ayrı bir hizmet hesabı kimliği kullanarak özel jetonlar oluşturmak için SDK'yı başlatın aşağıdaki gibidir:
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);
Python
options = {
'serviceAccountId': 'my-client-id@my-project-id.iam.gserviceaccount.com',
}
firebase_admin.initialize_app(options=options)
Go
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 olmadığından, bu kimliklerin açığa çıkması önemli değildir. Ancak özel jetonları belirtilen hizmet hesabıyla imzalamak için Firebase Admin SDK'nın uzak bir hizmeti çağırması gerekir.
Ayrıca, Yönetici SDK'si hizmet hesabının
bu aramayı yapmak için kullanılıyor
—genellikle {project-name}@appspot.gserviceaccount.com
—
iam.serviceAccounts.signBlob
özelliğine sahip
izni.
Daha ayrıntılı bilgi için aşağıdaki sorun giderme bölümüne bakın.
Firebase Admin SDK'yı kullanarak özel jetonlar oluşturma
Firebase Admin SDK'da, özel jetonlar oluşturmak için yerleşik bir yöntem bulunur. Kuyruklu a işareti
en azından bir uid
sağlamanız gerekir. Bu, herhangi bir dize olabilir ancak
kimliğini doğruladığınız kullanıcıyı veya cihazı benzersiz şekilde tanımlar. Bu jetonların süresi bir saat içinde dolacak.
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
İsteğe bağlı olarak özel jetona eklenecek ek iddialar da belirtebilirsiniz. Örneğin, aşağıdaki özel jetona bir premiumAccount
alanı eklenmiştir. Bu alan, Güvenlik Kurallarınızdaki auth
/request.auth
nesnelerinde kullanılabilir:
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
Ayrılmış özel jeton adları
İstemcilerde özel jetonları kullanarak oturum açma
Özel jeton oluşturduktan sonra bu jetonu istemci uygulamanıza göndermeniz gerekir. İlgili içeriği oluşturmak için kullanılan
istemci uygulaması, şunu çağırarak özel jetonla kimlik doğrular:
signInWithCustomToken()
:
iOS+
Objective-C
[[FIRAuth auth] signInWithCustomToken:customToken
completion:^(FIRAuthDataResult * _Nullable authResult,
NSError * _Nullable error) {
// ...
}];
Swift
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);
}
}
});
Unity
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.AuthResult result = task.Result;
Debug.LogFormat("User signed in successfully: {0} ({1})",
result.User.DisplayName, result.User.UserId);
});
C++
firebase::Future<firebase::auth::AuthResult> result =
auth->SignInWithCustomToken(custom_token);
Web
firebase.auth().signInWithCustomToken(token)
.then((userCredential) => {
// Signed in
var user = userCredential.user;
// ...
})
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
// ...
});
Web
import { getAuth, signInWithCustomToken } from "firebase/auth";
const auth = getAuth();
signInWithCustomToken(auth, token)
.then((userCredential) => {
// Signed in
const user = userCredential.user;
// ...
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
// ...
});
Kimlik doğrulama başarılı olursa kullanıcınız, özel jetona dahil edilen uid
tarafından belirtilen hesapla istemci uygulamanızda oturum açar. Bu hesap daha önce oluşturulmamışsa bu kullanıcının kaydı
oluşturuldu.
Bu yöntem, diğer oturum açma yöntemlerinde (ör.
signInWithEmailAndPassword()
ve signInWithCredential()
) auth
nesnesini tanımlayın
Realtime Database Security Rules ve
request.auth
nesnesindeki
Cloud Storage Security Rules
kullanıcının uid
ile doldurulur. Bu durumda, uid
özel jetonu oluştururken belirttiğinizdir.
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 iddialar içeriyorsa bu iddialara kurallarınızdaki auth.token
(Firebase Realtime Database) veya request.auth.token
(Cloud Storage) nesnesinden referans verilebilir:
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 jeton oluşturma
Arka ucunuz resmi bir Firebase Yöneticisi olmayan bir dildeyse SDK'yı kullanıyorsanız özel jetonları manuel olarak oluşturmaya devam edebilirsiniz. Öncelikle, diliniz için üçüncü taraf JWT kitaplığı bulun. Ardından, aşağıdaki hak taleplerini içeren bir JWT oluşturmak için bu JWT kitaplığını kullanın:
Özel jeton talepleri | ||
---|---|---|
alg |
Algoritma | "RS256" |
iss |
Düzenleyen | Projenizin hizmet hesabı e-posta adresi |
sub |
Konu | Projenizin hizmet hesabı e-posta adresi |
aud |
Kitle | "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit" |
iat |
Yayınlanma zamanı | UNIX sıfır zamanından itibaren saniye cinsinden geçerli zaman |
exp |
Geçerlilik süresi |
Jetonun süresinin dolacağı UNIX döneminden beri geçen süre (saniye cinsinden). Google
iat değerinden en fazla 3.600 saniye sonra olabilir.
. Not: Bu yalnızca özel jetonun sona erecektir. Ancak signInWithCustomToken() kullanarak bir kullanıcının oturumunu açtıktan sonra, oturumu geçersiz kılınana veya kullanıcı oturumu kapatana kadar cihazda oturumu açık kalır.
|
uid |
Oturum açmış kullanıcının benzersiz tanımlayıcısı,
1-128 karakter uzunluğunda (bu değerler dahil). Daha kısa uid değerleri daha iyi sonuç verir
bazı yolları da görmüştük.
|
|
claims (isteğe bağlı) |
Güvenlik Kurallarına dahil edilecek isteğe bağlı özel hak talepleri auth /
request.auth değişken
|
Firebase Admin SDK'sının desteklemediği çeşitli dillerde özel jeton oluşturma ile ilgili bazı örnek uygulamalar aşağıda verilmiştir:
PHP
php-jwt
kullanılıyor:
// 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
kullanılıyor:
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ğrulama yapmak için istemci uygulamanıza gönderin. Bunu nasıl yapacağınız hakkında bilgi edinmek için yukarıdaki kod örneklerine bakın.
Sorun giderme
Bu bölümde, geliştiricilerin ödeme yaparken karşılaşabilecekleri bazı yaygın sorunlar ve bunların nasıl çözüleceğini öğreneceksiniz.
IAM API etkin değil
Jetonları imzalamak için bir hizmet hesabı kimliği belirtiyorsanız şuna benzer bir hata oluştu:
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'sı, 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 "API'yi etkinleştir"i tıklayın. düğmesini tıklayarak projeniz için etkinleştirin.
Hizmet hesabı gerekli izinlere sahip değil
Firebase Admin SDK'nın çalıştığı hizmet hesabı
iam.serviceAccounts.signBlob
izniniz varsa şuna benzer bir hata mesajı alabilirsiniz:
şu:
Permission iam.serviceAccounts.signBlob is required to perform this operation on service account projects/-/serviceAccounts/{your-service-account-id}.
Bunu çözmenin en kolay yolu "Hizmet Hesabı Jetonu Oluşturucu"yu vermektir
Söz konusu hizmet hesabına IAM rolü ekleyin, genellikle
{project-name}@appspot.gserviceaccount.com
:
- Google Cloud konsolunda IAM ve yönetici sayfasını açın.
- Projenizi seçin ve "Devam"ı tıklayın.
- Güncellemek istediğiniz hizmet hesabına karşılık gelen düzenle simgesini tıklayın.
- "Başka bir rol ekle"yi tıklayın.
- Arama filtresine "Hizmet Hesabı Jeton Oluşturucu" yazın ve sonuçlardan seçin.
- "Kaydet"i tıklayın. tıklayın.
IAM belgelerini inceleyin daha fazla bilgi almak veya gcloud komut satırı araçları.
Hizmet hesabı belirlenemedi
Aşağıdakine benzer bir hata mesajı alırsanız Firebase Admin SDK'sı doğru ş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şfetmesi için SDK'dan yararlanıyorsanız Kod, bir meta veri sunucusuyla yönetilen Google ortamına dağıtılır. Aksi takdirde, SDK'yı ilk kullanıma hazırlarken hizmet hesabı JSON dosyasını veya hizmet hesabı kimliğini belirtmeyi unutmayın.