Mengelola tenant Identity Platform secara terprogram
Dokumen ini menjelaskan cara menggunakan Identity Platform Admin SDK untuk mengelola tenant dan penggunanya secara terprogram. Beberapa aktivitas yang dapat Anda lakukan sebagai administrator antara lain:
Pengelolaan pengguna: Membuat, memperbarui, menghapus, dan mencantumkan pengguna untuk tenant tertentu.
Verifikasi identitas: Identifikasi pengguna aplikasi untuk membatasi akses ke resource di server Anda sendiri.
Impor pengguna: Migrasikan pengguna dari sistem autentikasi eksternal atau project atau tenant Identity Platform lainnya.
Kontrol akses dengan klaim kustom: Menentukan atribut khusus pada akun pengguna untuk tenant tertentu dan menerapkan berbagai strategi kontrol akses, seperti kontrol akses berbasis peran.
Pengelolaan sesi pengguna: Mencabut token refresh pengguna untuk tenant tertentu.
Link tindakan email: Membuat link email yang disesuaikan untuk reset sandi, login dengan link email, dan verifikasi email bagi pengguna tenant tertentu.
Pengelolaan tenant: Membuat, mencantumkan, mendapatkan, memperbarui, menghapus tenant untuk project Identity Platform tertentu.
Mengelola penyedia OIDC dan SAML di tenant: Mengelola konfigurasi OIDC dan SAML secara terprogram pada tenant yang ditentukan.
Sebelum memulai
Instal Admin SDK untuk Node.js, Java, Python, Go, atau C#.
Aktifkan multi-tenancy untuk project Google Cloud Anda.
Fitur yang didukung
Tabel berikut mencantumkan fitur yang didukung oleh setiap SDK di lingkungan multi-tenant:
Fitur | Node.js | Java | Python | Go | C# |
---|---|---|---|---|---|
Pembuatan token kustom | |||||
Memverifikasi token ID | |||||
Mengelola pengguna | |||||
Mengontrol akses dengan klaim kustom | |||||
Mencabut token refresh | |||||
Mengimpor pengguna | |||||
Membuat link tindakan email | |||||
Autentikasi multi-faktor | |||||
Mengelola konfigurasi penyedia SAML/OIDC | |||||
Pengelolaan cookie sesi |
Tabel berikut menunjukkan metode login yang dapat Anda konfigurasi menggunakan Admin SDK dan Konsol Google Cloud dalam konteks khusus tenant:
Fitur | Konsol Google Cloud | Admin SDK |
---|---|---|
OIDC | ||
SAML | ||
Sosial | ||
Telepon | ||
Autentikasi multi-faktor | ||
Anonim |
Manajemen penyewa
Dengan Admin SDK, Anda dapat mengelola tenant secara terprogram dari lingkungan server yang aman, bukan menggunakan Konsol Google Cloud. Hal ini mencakup kemampuan untuk membuat, mencantumkan, mendapatkan, mengubah, atau menghapus tenant.
Setiap tenant berisi penyedia identitas, setelan, dan kumpulan penggunanya sendiri.
Operasi manajemen konfigurasi tenant (CRUD) tersedia dari instance project
induk menggunakan admin.auth().tenantManager()
.
Konfigurasi tenant memberikan informasi tentang tenant, seperti nama tampilan, ID tenant, dan konfigurasi autentikasi emailnya.
Semua setelan lainnya (seperti domain yang diizinkan dan URI pengalihan yang diautentikasi) tenant akan diwariskan dari project induk. Layanan ini harus dikelola menggunakan Konsol Google Cloud.
Untuk operasi seperti pengelolaan pengguna khusus tenant, mengonfigurasi penyedia OIDC/SAML, dan pembuatan link email, Anda memerlukan instance TenantAwareAuth
untuk tenant target (yang diidentifikasi oleh tenantId
uniknya).
Node.js
const tenantManager = admin.auth().tenantManager();
const tenantAuth = tenantManager.authForTenant(tenantId);
Python
from firebase_admin import tenant_mgt tenant_client = tenant_mgt.auth_for_tenant(tenant_id)
Java
FirebaseAuth auth = FirebaseAuth.getInstance(); TenantManager tenantManager = auth.getTenantManager(); TenantAwareFirebaseAuth tenantAuth = tenantManager.getAuthForTenant(tenantId);
Semua panggilan ke API pengelolaan pengguna, API pengelolaan penyedia OIDC/SAML, dan API pembuatan link email akan berada dalam cakupan tenant ini (menggunakan instance TenantAwareAuth
).
Mendapatkan tenant yang ada
Admin SDK menyediakan metode getTenant()
, yang mengambil informasi tentang tenant berdasarkan tenantId
-nya (ID unik untuk tenant).
Node.js
admin.auth().tenantManager().getTenant(tenantId)
.then((tenant) => {
console.log(tenant.toJSON());
})
.catch((error) => {
// Handle error.
});
Python
tenant = tenant_mgt.get_tenant(tenant_id) print('Retreieved tenant:', tenant.tenant_id)
Java
Tenant tenant = FirebaseAuth.getInstance().getTenantManager().getTenant(tenantId); System.out.println("Retrieved tenant: " + tenant.getTenantId());
Metode ini menampilkan objek Tenant
yang sesuai dengan tenantId
.
Jika tenantId
yang diberikan bukan milik tenant yang ada, promise yang ditampilkan akan ditolak dengan error auth/tenant-not-found
.
Berhati-hatilah agar tidak tertukar antara instance Tenant
dengan objek
TenantAwareAuth
. authInstance.tenantManager().authForTenant()
menampilkan
instance TenantAwareAuth
yang memperluas
BaseAuth
.
Class Auth
juga memperluas BaseAuth
.
BaseAuth
menyediakan API untuk mengelola pengguna, mengonfigurasi penyedia OIDC/SAML dalam berbagai konteks. Untuk Auth
, konteksnya berada di level project induk.
Untuk TenantAwareAuth
, konteksnya berada di level tenant (tenant ditentukan oleh ID tenant). Metode getTenant()
akan di-resolve dengan informasi tenant dasar (seperti ID tenant, nama tampilan, dan setelan penyedia email), tetapi untuk memanggil API di tenant tersebut, Anda perlu menggunakan authForTenant(tenantFromGetTenant.tenantId)
.
Membuat tenant
Gunakan metode createTenant()
untuk membuat konfigurasi tenant baru:
Node.js
admin.auth().tenantManager().createTenant({
displayName: 'myTenant1',
emailSignInConfig: {
enabled: true,
passwordRequired: false, // Email link sign-in enabled.
},
// TODO: Remove if you don't want to enable multi-factor authentication.
multiFactorConfig: {
state: 'ENABLED',
factorIds: ['phone']
},
// TODO: Remove if you don't want to register test phone numbers for use
// with multi-factor authentication.
testPhoneNumbers: {
'+16505551234': '145678',
'+16505550000': '123456'
},
})
.then((createdTenant) => {
console.log(createdTenant.toJSON());
})
.catch((error) => {
// Handle error.
});
Python
tenant = tenant_mgt.create_tenant( display_name='myTenant1', enable_email_link_sign_in=True, allow_password_sign_up=True) print('Created tenant:', tenant.tenant_id)
Java
Tenant.CreateRequest request = new Tenant.CreateRequest() .setDisplayName("myTenant1") .setEmailLinkSignInEnabled(true) .setPasswordSignInAllowed(true); Tenant tenant = FirebaseAuth.getInstance().getTenantManager().createTenant(request); System.out.println("Created tenant: " + tenant.getTenantId());
Anda dapat memberikan kombinasi properti ini:
Properti | Jenis | Deskripsi |
---|---|---|
displayName |
string |
Nama tampilan tenant. Kolom ini harus terdiri dari 4-20 karakter, yang terdiri dari huruf, angka, dan tanda hubung, serta harus diawali dengan huruf. |
emailSignInConfig |
{ enable: boolean, passwordRequired: boolean } |
Konfigurasi penyedia login email. Hal ini termasuk apakah penyedia email diaktifkan atau tidak, dan apakah sandi diperlukan untuk login dengan email. Jika tidak diwajibkan, login dengan email dapat dilakukan dengan sandi atau menggunakan metode login dengan link email. |
multiFactorConfig |
{ state: 'DISABLED' | 'ENABLED', factorIds: string[] } |
Apakah autentikasi multi-faktor diaktifkan untuk tenant, dan jenis faktor yang diizinkan. Saat ini, satu-satunya ID faktor yang didukung adalah phone .
|
testPhoneNumbers |
{ string: string } |
Peta nomor telepon dan kode autentikasi multi-faktor yang terkait untuk didaftarkan untuk tujuan pengujian.
Anda hanya boleh mengirimkan maksimum 10 entri. Untuk menghapus semua nomor telepon pengujian, tetapkan
kolom ini ke null .
|
Metode ini menampilkan objek Tenant
untuk tenant yang baru dibuat.
Memperbarui tenant
Gunakan metode updateTenant()
untuk mengubah data tenant yang ada. Anda harus menentukan tenantId
, beserta properti yang akan diperbarui untuk tenant tersebut.
Node.js
admin.auth().tenantManager().updateTenant(tenantId, {
displayName: 'updatedName',
emailSignInConfig: {
enabled: false, // Disable email provider.
},
// Enable multi-factor authentication.
multiFactorConfig: {
state: 'ENABLED',
factorIds: ['phone']
},
// Register phone numbers for testing.
testPhoneNumbers: {
'+16505551234': '145678',
'+16505550000': '123456'
},
})
.then((updatedTenant) => {
console.log(updatedTenant.toJSON());
})
.catch((error) => {
// Handle error.
});
Python
tenant = tenant_mgt.update_tenant( tenant_id, display_name='updatedName', allow_password_sign_up=False) # Disable email provider print('Updated tenant:', tenant.tenant_id)
Java
Tenant.UpdateRequest request = new Tenant.UpdateRequest(tenantId) .setDisplayName("updatedName") .setPasswordSignInAllowed(false); Tenant tenant = FirebaseAuth.getInstance().getTenantManager().updateTenant(request); System.out.println("Updated tenant: " + tenant.getTenantId());
updateTenant()
menerima properti yang sama seperti createTenant()
. Semua properti
bersifat opsional. Jika properti tidak ditentukan, nilai yang ada tidak akan diubah.
Metode ini akan menampilkan objek Tenant
yang diperbarui setelah selesai. Jika tenantId
yang disediakan bukan milik tenant yang ada, promise yang ditampilkan akan ditolak dengan error auth/tenant-not-found
.
Menghapus tenant
Anda dapat menghapus tenant menggunakan tenantId
-nya:
Node.js
admin.auth().tenantManager().deleteTenant(tenantId)
.then(() => {
// Tenant deleted.
})
.catch((error) => {
// Handle error.
});
Python
tenant_mgt.delete_tenant(tenant_id)
Java
FirebaseAuth.getInstance().getTenantManager().deleteTenant(tenantId);
Metode ini akan menampilkan hasil kosong saat penghapusan berhasil diselesaikan.
Jika tenantId
yang diberikan bukan milik tenant yang ada, promise yang ditampilkan akan ditolak dengan error auth/tenant-not-found
.
Mencantumkan tenant
Gunakan metode listTenants()
untuk menampilkan tenant yang ada:
Node.js
function listAllTenants(nextPageToken) {
return admin.auth().tenantManager().listTenants(100, nextPageToken)
.then((result) => {
result.tenants.forEach((tenant) => {
console.log(tenant.toJSON());
});
if (result.pageToken) {
return listAllTenants(result.pageToken);
}
});
}
listAllTenants();
Python
for tenant in tenant_mgt.list_tenants().iterate_all(): print('Retrieved tenant:', tenant.tenant_id)
Java
ListTenantsPage page = FirebaseAuth.getInstance().getTenantManager().listTenants(null); for (Tenant tenant : page.iterateAll()) { System.out.println("Retrieved tenant: " + tenant.getTenantId()); }
Setiap batch hasil berisi daftar tenant, ditambah token halaman berikutnya untuk menampilkan daftar batch tenant berikutnya. Setelah semua tenant sudah tercantum, tidak ada pageToken
yang ditampilkan.
Jika tidak ada kolom maxResults
yang ditentukan, defaultnya adalah 1.000 tenant per batch.
Ini juga merupakan jumlah maksimum tenant yang diizinkan untuk dicantumkan dalam satu waktu.
Nilai apa pun yang lebih besar dari nilai maksimum akan menampilkan error argumen.
Jika pageToken
tidak ditentukan, metode ini akan mencantumkan tenant dari awal.
Mengelola penyedia SAML dan OIDC secara terprogram
Admin SDK menyediakan API untuk mengelola konfigurasi penyedia Security Assertion Markup Language (SAML) 2.0 dan OpenID Connect (OIDC) secara terprogram dari lingkungan server yang aman.
Dengan Admin SDK, Anda dapat mengelola penyedia ini untuk tenant tertentu. Hal ini mirip dengan mengelola penyedia OIDC dan SAML tingkat project.
Untuk mengelola penyedia untuk tenant, buat instance TenantAwareAuth
terlebih dahulu:
Node.js
const tenantAuth = admin.auth().tenantManager().authForTenant('TENANT-ID');
Python
tenant_client = tenant_mgt.auth_for_tenant('TENANT-ID')
Java
TenantAwareFirebaseAuth tenantAuth = FirebaseAuth.getInstance().getTenantManager() .getAuthForTenant("TENANT-ID");
Kemudian, Anda dapat melakukan operasi umum, seperti membuat, mengubah, atau menghapus penyedia untuk tenant.
Membuat penyedia
Kode berikut menunjukkan cara membuat penyedia SAML untuk tenant:
Node.js
const newConfig = {
displayName: 'SAML provider name',
enabled: true,
providerId: 'saml.myProvider',
idpEntityId: 'IDP_ENTITY_ID',
ssoURL: 'https://example.com/saml/sso/1234/',
x509Certificates: [
'-----BEGIN CERTIFICATE-----\nCERT1...\n-----END CERTIFICATE-----',
'-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----'
],
rpEntityId: 'RP_ENTITY_ID',
// Using the default callback URL.
callbackURL: 'https://project-id.firebaseapp.com/__/auth/handler'
};
tenantAuth.createProviderConfig(newConfig).then(() => {
// Successful creation.
}).catch((error) => {
// Handle error.
});
Python
saml = tenant_client.create_saml_provider_config( display_name='SAML provider name', enabled=True, provider_id='saml.myProvider', idp_entity_id='IDP_ENTITY_ID', sso_url='https://example.com/saml/sso/1234/', x509_certificates=[ '-----BEGIN CERTIFICATE-----\nCERT1...\n-----END CERTIFICATE-----', '-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----', ], rp_entity_id='P_ENTITY_ID', callback_url='https://project-id.firebaseapp.com/__/auth/handler') print('Created new SAML provider:', saml.provider_id)
Java
SamlProviderConfig.CreateRequest request = new SamlProviderConfig.CreateRequest() .setDisplayName("SAML provider name") .setEnabled(true) .setProviderId("saml.myProvider") .setIdpEntityId("IDP_ENTITY_ID") .setSsoUrl("https://example.com/saml/sso/1234/") .addX509Certificate("-----BEGIN CERTIFICATE-----\nCERT1...\n-----END CERTIFICATE-----") .addX509Certificate("-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----") .setRpEntityId("RP_ENTITY_ID") .setCallbackUrl("https://project-id.firebaseapp.com/__/auth/handler"); SamlProviderConfig saml = tenantAuth.createSamlProviderConfig(request); System.out.println("Created new SAML provider: " + saml.getProviderId());
Mengubah penyedia
Kode berikut menunjukkan cara mengubah penyedia:
Node.js
const updatedConfig = {
x509Certificates: [
'-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----',
'-----BEGIN CERTIFICATE-----\nCERT3...\n-----END CERTIFICATE-----',
],
};
tenantAuth.updateProviderConfig('saml.myProvider', updatedConfig).then(() => {
// Successful update.
}).catch((error) => {
// Handle error.
});
Python
saml = tenant_client.update_saml_provider_config( 'saml.myProvider', x509_certificates=[ '-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----', '-----BEGIN CERTIFICATE-----\nCERT3...\n-----END CERTIFICATE-----', ]) print('Updated SAML provider:', saml.provider_id)
Java
SamlProviderConfig.UpdateRequest request = new SamlProviderConfig.UpdateRequest("saml.myProvider") .addX509Certificate("-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----") .addX509Certificate("-----BEGIN CERTIFICATE-----\nCERT3...\n-----END CERTIFICATE-----"); SamlProviderConfig saml = tenantAuth.updateSamlProviderConfig(request); System.out.println("Updated SAML provider: " + saml.getProviderId());
Mendapatkan penyedia
Kode berikut menunjukkan cara mengambil konfigurasi penyedia untuk tenant tertentu menggunakan ID penyedianya:
Node.js
tenantAuth.getProviderConfig('saml.myProvider').then((config) => {
// Get display name and whether it is enabled.
console.log(config.displayName, config.enabled);
}).catch((error) => {
// Handle error. Common error is that config is not found.
});
Python
saml = tennat_client.get_saml_provider_config('saml.myProvider') print(saml.display_name, saml.enabled)
Java
SamlProviderConfig saml = tenantAuth.getSamlProviderConfig("saml.myProvider"); // Get display name and whether it is enabled. System.out.println(saml.getDisplayName() + " " + saml.isEnabled());
Penyedia listingan
Kode berikut menunjukkan cara menampilkan daftar konfigurasi penyedia untuk tenant tertentu:
Node.js
// Returns 10 SAML provider configs starting from the specified nextPageToken offset.
tenantAuth.listProviderConfigs({type: 'saml', maxResults: 10, pageToken: 'nextPageToken'}).then((results) => {
results.providerConfigs.forEach((config) => {
console.log(config.providerId);
});
// To list the next 10:
// return tenantAuth.listProviderConfigs(
// {type: 'saml', maxResults: 10, pageToken: results.pageToken});
}).catch((error) => {
// Handle error.
});
Python
for saml in tenant_client.list_saml_provider_configs('nextPageToken').iterate_all(): print(saml.provider_id)
Java
ListProviderConfigsPage<SamlProviderConfig> page = tenantAuth.listSamlProviderConfigs( "nextPageToken"); for (SamlProviderConfig saml : page.iterateAll()) { System.out.println(saml.getProviderId()); }
Menghapus penyedia
Kode berikut menunjukkan cara menghapus penyedia:
Node.js
tenantAuth.deleteProviderConfig('saml.myProvider').then(() => {
// Successful deletion.
}).catch((error) => {
// Handle error.
});
Python
tenant_client.delete_saml_provider_config('saml.myProvider')
Java
tenantAuth.deleteSamlProviderConfig("saml.myProvider");
Penyedia OIDC dikelola seperti penyedia OIDC level project, kecuali
penyedia OIDC dapat dikelola dari instance TenantAwareAuth
yang terkait, bukan
instance level project Auth
.
Untuk mempelajari lebih lanjut, lihat Mengelola penyedia SAML dan OIDC secara terprogram.
Mengelola pengguna khusus tenant
Anda dapat menggunakan Admin SDK untuk membuat, mengambil, memperbarui, menghapus, dan menampilkan daftar semua pengguna untuk tenant tertentu.
Untuk memulai, Anda memerlukan instance TenantAwareAuth
untuk tenant yang sesuai:
Node.js
const tenantAuth = admin.auth().tenantManager().authForTenant('TENANT-ID');
Python
tenant_client = tenant_mgt.auth_for_tenant('TENANT-ID')
Java
TenantAwareFirebaseAuth tenantAuth = FirebaseAuth.getInstance().getTenantManager() .getAuthForTenant("TENANT-ID");
Mendapatkan pengguna
Anda dapat mengambil pengguna khusus tenant dengan ID uid
:
Node.js
tenantAuth.getUser(uid)
.then((userRecord) => {
// See the UserRecord reference documentation to learn more.
console.log('Successfully fetched user data:', userRecord.toJSON());
// Tenant ID will be reflected in userRecord.tenantId.
})
.catch((error) => {
console.log('Error fetching user data:', error);
});
Python
# Get an auth.Client from tenant_mgt.auth_for_tenant() user = tenant_client.get_user(uid) print('Successfully fetched user data:', user.uid)
Java
// Get an auth client from the firebase.App UserRecord user = tenantAuth.getUser(uid); System.out.println("Successfully fetched user data: " + user.getDisplayName());
Anda juga dapat mengidentifikasi pengguna melalui emailnya:
Node.js
tenantAuth.getUserByEmail(email)
.then((userRecord) => {
// See the UserRecord reference documentation to learn more.
console.log('Successfully fetched user data:', userRecord.toJSON());
// Tenant ID will be reflected in userRecord.tenantId.
})
.catch((error) => {
console.log('Error fetching user data:', error);
});
Python
user = tenant_client.get_user_by_email(email) print('Successfully fetched user data:', user.uid)
Java
// Get an auth client from the firebase.App UserRecord user = tenantAuth.getUserByEmail(email); System.out.println("Successfully fetched user data: " + user.getDisplayName());
Membuat pengguna
Gunakan metode createUser()
untuk membuat pengguna baru untuk tenant tertentu.
Saat membuat pengguna baru, pemberian uid
bersifat opsional. Jika tidak ditentukan, Identity Platform akan menyediakan pengguna yang unik.
Node.js
tenantAuth.createUser({
email: 'user@example.com',
emailVerified: false,
phoneNumber: '+11234567890',
password: 'secretPassword',
displayName: 'John Doe',
photoURL: 'http://www.example.com/12345678/photo.png',
disabled: false
})
.then((userRecord) => {
// See the UserRecord reference documentation to learn more.
console.log('Successfully created new user:', userRecord.uid);
// Tenant ID will be reflected in userRecord.tenantId.
})
.catch((error) => {
console.log('Error creating new user:', error);
});
Python
user = tenant_client.create_user( email='user@example.com', email_verified=False, phone_number='+15555550100', password='secretPassword', display_name='John Doe', photo_url='http://www.example.com/12345678/photo.png', disabled=False) print('Sucessfully created new user:', user.uid)
Java
UserRecord.CreateRequest request = new UserRecord.CreateRequest() .setEmail("user@example.com") .setEmailVerified(false) .setPhoneNumber("+15555550100") .setPassword("secretPassword") .setDisplayName("John Doe") .setPhotoUrl("http://www.example.com/12345678/photo.png") .setDisabled(false); UserRecord user = tenantAuth.createUser(request); System.out.println("Successfully created user: " + user.getDisplayName());
Mengubah pengguna
Anda dapat memodifikasi pengguna yang ada dengan menentukan uid
mereka ke metode updateUser()
:
Node.js
tenantAuth.updateUser(uid, {
email: 'modifiedUser@example.com',
phoneNumber: '+11234567890',
emailVerified: true,
password: 'newPassword',
displayName: 'Jane Doe',
photoURL: 'http://www.example.com/12345678/photo.png',
disabled: true
})
.then((userRecord) => {
// See the UserRecord reference documentation to learn more.
console.log('Successfully updated user', userRecord.toJSON());
})
.catch((error) => {
console.log('Error updating user:', error);
});
Python
user = tenant_client.update_user( uid, email='user@example.com', phone_number='+15555550100', email_verified=True, password='newPassword', display_name='John Doe', photo_url='http://www.example.com/12345678/photo.png', disabled=True) print('Sucessfully updated user:', user.uid)
Java
UserRecord.UpdateRequest request = new UserRecord.UpdateRequest(uid) .setEmail("user@example.com") .setEmailVerified(true) .setPhoneNumber("+15555550100") .setPassword("newPassword") .setDisplayName("John Doe") .setPhotoUrl("http://www.example.com/12345678/photo.png") .setDisabled(true); UserRecord user = tenantAuth.updateUser(request); System.out.println("Successfully updated user: " + user.getDisplayName());
Menghapus pengguna
Contoh berikut menunjukkan cara menghapus pengguna berdasarkan uid
mereka:
Node.js
tenantAuth.deleteUser(uid)
.then(() => {
console.log('Successfully deleted user');
})
.catch((error) => {
console.log('Error deleting user:', error);
});
Python
tenant_client.delete_user(uid) print('Successfully deleted user')
Java
tenantAuth.deleteUser(uid); System.out.println("Successfully deleted user: " + uid);
Menampilkan daftar pengguna
Untuk mengambil seluruh daftar pengguna untuk tenant tertentu dalam batch, gunakan metode listUsers()
. Setiap batch akan berisi daftar data pengguna, ditambah token halaman berikutnya jika ada pengguna tambahan.
Node.js
function listAllUsers(nextPageToken) {
// List batch of users, 1000 at a time.
tenantAuth.listUsers(1000, nextPageToken)
.then((listUsersResult) => {
listUsersResult.users.forEach((userRecord) => {
console.log('user', userRecord.toJSON());
// Tenant ID will be reflected in userRecord.tenantId.
});
if (listUsersResult.pageToken) {
// List next batch of users.
listAllUsers(listUsersResult.pageToken);
}
})
.catch((error) => {
console.log('Error listing users:', error);
});
}
// Start listing users from the beginning, 1000 at a time.
listAllUsers();
Python
# Note, behind the scenes, the iterator will retrive 1000 users at a time through the API for user in tenant_client.list_users().iterate_all(): print('User: ' + user.uid) # Iterating by pages of 1000 users at a time. page = tenant_client.list_users() while page: for user in page.users: print('User: ' + user.uid) # Get next batch of users. page = page.get_next_page()
Java
// Note, behind the scenes, the ListUsersPage retrieves 1000 Users at a time // through the API ListUsersPage page = tenantAuth.listUsers(null); for (ExportedUserRecord user : page.iterateAll()) { System.out.println("User: " + user.getUid()); } // Iterating by pages 100 users at a time. page = tenantAuth.listUsers(null, 100); while (page != null) { for (ExportedUserRecord user : page.getValues()) { System.out.println("User: " + user.getUid()); } page = page.getNextPage(); }
Baca dokumentasi Admin SDK mengenai mengelola pengguna untuk mempelajari lebih lanjut.
Mengimpor pengguna
Anda dapat menggunakan Admin SDK untuk mengimpor pengguna secara massal ke tenant tertentu dengan hak istimewa yang ditingkatkan. Hal ini menawarkan banyak manfaat, seperti kemampuan untuk memigrasikan pengguna dari produk Identity Platform lainnya, dari tenant lain, atau dari sistem autentikasi eksternal menggunakan algoritma hashing yang berbeda. Anda juga dapat mengimpor pengguna dengan penyedia gabungan (seperti SAML dan OIDC) serta klaim kustom secara langsung secara massal.
Untuk memulai, dapatkan instance TenantAwareAuth
untuk tenant yang sesuai:
Node.js
const tenantAuth = admin.auth().tenantManager().authForTenant('TENANT-ID');
Python
tenant_client = tenant_mgt.auth_for_tenant('TENANT-ID')
Java
TenantAwareFirebaseAuth tenantAuth = FirebaseAuth.getInstance().getTenantManager() .getAuthForTenant("TENANT-ID");
Anda dapat mengimpor hingga 1.000 pengguna sekaligus menggunakan algoritma hashing tertentu.
Node.js
tenantAuth.importUsers([{
uid: 'uid1',
email: 'user1@example.com',
// Must be provided in a byte buffer.
passwordHash: Buffer.from('password-hash-1'),
// Must be provided in a byte buffer.
passwordSalt: Buffer.from('salt1')
},
{
uid: 'uid2',
email: 'user2@example.com',
// Must be provided in a byte buffer.
passwordHash: Buffer.from('password-hash-2'),
// Must be provided in a byte buffer.
passwordSalt: Buffer.from('salt2')
}], {
hash: {
algorithm: 'HMAC_SHA256',
// Must be provided in a byte buffer.
key: Buffer.from('secret')
}
})
.then((results) => {
results.errors.forEach(function(indexedError) {
console.log('Error importing user ' + indexedError.index);
});
})
.catch((error) => {
console.log('Error importing users:', error);
});
Python
users = [ auth.ImportUserRecord( uid='uid1', email='user1@example.com', password_hash=b'password_hash_1', password_salt=b'salt1' ), auth.ImportUserRecord( uid='uid2', email='user2@example.com', password_hash=b'password_hash_2', password_salt=b'salt2' ), ] hash_alg = auth.UserImportHash.hmac_sha256(key=b'secret') try: result = tenant_client.import_users(users, hash_alg=hash_alg) for err in result.errors: print('Failed to import user:', err.reason) except exceptions.FirebaseError as error: print('Error importing users:', error)
Java
List<ImportUserRecord> users = new ArrayList<>(); users.add(ImportUserRecord.builder() .setUid("uid1") .setEmail("user1@example.com") .setPasswordHash("password-hash-1".getBytes()) .setPasswordSalt("salt1".getBytes()) .build()); users.add(ImportUserRecord.builder() .setUid("uid2") .setEmail("user2@example.com") .setPasswordHash("password-hash-2".getBytes()) .setPasswordSalt("salt2".getBytes()) .build()); UserImportHash hmacSha256 = HmacSha256.builder() .setKey("secret".getBytes()) .build(); UserImportResult result = tenantAuth.importUsers(users, UserImportOptions.withHash(hmacSha256)); for (ErrorInfo error : result.getErrors()) { System.out.println("Failed to import user: " + error.getReason()); }
tenantId
akan ditetapkan ke tenantAuth.tenantId
untuk semua pengguna yang diimpor.
Pengguna tanpa sandi juga dapat diimpor ke tenant tertentu. Pengguna ini dapat diimpor dengan penyedia gabungan dan klaim kustom.
Node,js
tenantAuth.importUsers([{
uid: 'some-uid',
displayName: 'John Doe',
email: 'johndoe@acme.com',
photoURL: 'http://www.example.com/12345678/photo.png',
emailVerified: true,
phoneNumber: '+11234567890',
// Set this user as admin.
customClaims: {admin: true},
// User with SAML provider.
providerData: [{
uid: 'saml-uid',
email: 'johndoe@acme.com',
displayName: 'John Doe',
photoURL: 'http://www.example.com/12345678/photo.png',
providerId: 'saml.acme'
}]
}])
.then(function(results) {
results.errors.forEach(function(indexedError) {
console.log('Error importing user ' + indexedError.index);
});
})
.catch(function(error) {
console.log('Error importing users:', error);
});
Python
users = [ auth.ImportUserRecord( uid='some-uid', display_name='John Doe', email='johndoe@gmail.com', photo_url='http://www.example.com/12345678/photo.png', email_verified=True, phone_number='+11234567890', custom_claims={'admin': True}, # set this user as admin provider_data=[ # user with SAML provider auth.UserProvider( uid='saml-uid', email='johndoe@gmail.com', display_name='John Doe', photo_url='http://www.example.com/12345678/photo.png', provider_id='saml.acme' ) ], ), ] try: result = tenant_client.import_users(users) for err in result.errors: print('Failed to import user:', err.reason) except exceptions.FirebaseError as error: print('Error importing users:', error)
Java
List<ImportUserRecord> users = new ArrayList<>(); users.add(ImportUserRecord.builder() .setUid("some-uid") .setDisplayName("John Doe") .setEmail("johndoe@acme.com") .setPhotoUrl("https://www.example.com/12345678/photo.png") .setEmailVerified(true) .setPhoneNumber("+11234567890") // Set this user as admin. .putCustomClaim("admin", true) // User with SAML provider. .addUserProvider(UserProvider.builder() .setUid("saml-uid") .setEmail("johndoe@acme.com") .setDisplayName("John Doe") .setPhotoUrl("https://www.example.com/12345678/photo.png") .setProviderId("saml.acme") .build()) .build()); UserImportResult result = tenantAuth.importUsers(users); for (ErrorInfo error : result.getErrors()) { System.out.println("Failed to import user: " + error.getReason()); }
Lihat Mengimpor pengguna di dokumentasi Admin SDK untuk mempelajari lebih lanjut.
Verifikasi identitas (IDV)
Ketika aplikasi klien Identity Platform berkomunikasi dengan server backend khusus, pengguna yang sedang login harus diidentifikasi di server tersebut. Hal ini dapat dilakukan secara aman dengan mengirimkan token ID pengguna setelah berhasil login menggunakan koneksi yang aman ke server Anda. Selanjutnya, server dapat memverifikasi integritas dan keaslian token ID.
Admin SDK memiliki metode bawaan untuk memverifikasi dan mendekode token ID untuk tenant tertentu.
Setelah berhasil memproses login pengguna ke tenant tertentu dari klien, ambil token ID pengguna menggunakan SDK Klien:
auth.tenantId = 'TENANT-ID';
auth.signInWithEmailAndPassword('user@example.com', 'password')
.then((userCredential) => {
return userCredential.user.getIdToken();
})
.then((idToken) => {
// Send the ID token to server for verification. ID token should be scoped to TENANT-ID.
});
Buat instance TenantAwareAuth
di server:
Node.js
const tenantAuth = admin.auth().tenantManager().authForTenant('TENANT-ID');
Python
tenant_client = tenant_mgt.auth_for_tenant('TENANT-ID')
Java
TenantAwareFirebaseAuth tenantAuth = FirebaseAuth.getInstance().getTenantManager() .getAuthForTenant("TENANT-ID");
Kemudian, Anda dapat memverifikasi token ID untuk tenant tersebut:
Node.js
// idToken comes from the client app
tenantAuth.verifyIdToken(idToken)
.then((decodedToken) => {
let uid = decodedToken.uid;
// This should be set to TENANT-ID. Otherwise auth/mismatching-tenant-id error thrown.
console.log(decodedToken.firebase.tenant);
// ...
}).catch((error) => {
// Handle error
});
Resource sisi server mungkin dapat diakses oleh beberapa tenant dengan tingkat akses yang berbeda. Dalam hal ini, karena ID tenant mungkin tidak diketahui sebelumnya, token ID dapat diverifikasi di level project terlebih dahulu.
admin.auth().verifyIdToken(idToken)
.then((decodedToken) => {
if (decodedToken.firebase.tenant === 'TENANT-ID1') {
// Allow appropriate level of access for TENANT-ID1.
} else if (decodedToken.firebase.tenant === 'TENANT-ID2') {
// Allow appropriate level of access for TENANT-ID2.
} else {
// Block access for all other tenants.
throw new Error('Access not allowed.');
}
}).catch((error) => {
// Handle error
});
Python
# id_token comes from the client app try: decoded_token = tenant_client.verify_id_token(id_token) # This should be set to TENANT-ID. Otherwise TenantIdMismatchError error raised. print('Verified ID token from tenant:', decoded_token['firebase']['tenant']) except tenant_mgt.TenantIdMismatchError: # Token revoked, inform the user to reauthenticate or signOut(). pass
Java
try { // idToken comes from the client app FirebaseToken token = tenantAuth.verifyIdToken(idToken); // TenantId on the FirebaseToken should be set to TENANT-ID. // Otherwise "tenant-id-mismatch" error thrown. System.out.println("Verified ID token from tenant: " + token.getTenantId()); } catch (FirebaseAuthException e) { System.out.println("error verifying ID token: " + e.getMessage()); }
Baca dokumentasi Admin SDK tentang memverifikasi token ID untuk mempelajari lebih lanjut.
Mengelola sesi pengguna
Sesi Identity Platform berlangsung lama. Setiap kali pengguna login, kredensial pengguna tersebut akan diverifikasi di server Identity Platform, lalu ditukar dengan token ID yang memiliki masa aktif singkat dan token refresh yang memiliki masa aktif lama. Token ID berlaku selama satu jam. Token refresh tidak memiliki masa berlaku, kecuali jika pengguna dinonaktifkan, dihapus, atau mengalami perubahan akun yang besar (seperti email atau pembaruan sandi).
Dalam beberapa kasus, token refresh pengguna mungkin perlu dicabut karena alasan keamanan, seperti pengguna melaporkan perangkat yang hilang atau dicuri, penemuan kerentanan umum dalam aplikasi, atau kebocoran token aktif dalam skala besar. Admin SDK menyediakan API untuk mencabut semua token refresh yang dikeluarkan untuk pengguna yang ditentukan dari tenant tertentu.
Untuk memulai, Anda memerlukan instance TenantAwareAuth
:
Node.js
const tenantAuth = admin.auth().tenantManager().authForTenant('TENANT-ID');
Python
tenant_client = tenant_mgt.auth_for_tenant('TENANT-ID')
Java
TenantAwareFirebaseAuth tenantAuth = FirebaseAuth.getInstance().getTenantManager() .getAuthForTenant("TENANT-ID");
Token refresh kemudian dapat dicabut dengan menetapkan uid
pengguna tersebut:
Node.js
// Revoke all refresh tokens for a specified user in a specified tenant for whatever reason.
// Retrieve the timestamp of the revocation, in seconds since the epoch.
tenantAuth.revokeRefreshTokens(uid)
.then(() => {
return tenantAuth.getUser(uid);
})
.then((userRecord) => {
return new Date(userRecord.tokensValidAfterTime).getTime() / 1000;
})
.then((timestamp) => {
console.log('Tokens revoked at: ', timestamp);
});
Python
# Revoke all refresh tokens for a specified user in a specified tenant for whatever reason. # Retrieve the timestamp of the revocation, in seconds since the epoch. tenant_client.revoke_refresh_tokens(uid) user = tenant_client.get_user(uid) # Convert to seconds as the auth_time in the token claims is in seconds. revocation_second = user.tokens_valid_after_timestamp / 1000 print('Tokens revoked at: {0}'.format(revocation_second))
Java
// Revoke all refresh tokens for a specified user in a specified tenant for whatever reason. // Retrieve the timestamp of the revocation, in seconds since the epoch. tenantAuth.revokeRefreshTokens(uid); // accessing the user's TokenValidAfter UserRecord user = tenantAuth.getUser(uid); long timestamp = user.getTokensValidAfterTimestamp() / 1000; System.out.println("the refresh tokens were revoked at: " + timestamp + " (UTC seconds)");
Setelah token refresh dicabut, tidak ada token ID baru yang dapat dikeluarkan untuk pengguna tersebut hingga mereka melakukan autentikasi ulang. Namun, token ID yang ada akan tetap aktif hingga waktu habis masa berlakunya normalnya (satu jam).
Anda dapat memverifikasi bahwa token ID valid yang belum habis masa berlakunya tidak dicabut dengan menentukan
parameter checkRevoked
opsional; metode ini akan memeriksa apakah token dicabut setelah
integritas dan keasliannya diverifikasi.
Node.js
// Verify the ID token for a specific tenant while checking if the token is revoked by passing
// checkRevoked true.
let checkRevoked = true;
tenantAuth.verifyIdToken(idToken, checkRevoked)
.then(payload => {
// Token is valid.
})
.catch(error => {
if (error.code == 'auth/id-token-revoked') {
// Token has been revoked. Inform the user to re-authenticate or
// signOut() the user.
} else {
// Token is invalid.
}
});
Python
# Verify the ID token for a specific tenant while checking if the token is revoked. try: # Verify the ID token while checking if the token is revoked by # passing check_revoked=True. decoded_token = tenant_client.verify_id_token(id_token, check_revoked=True) # Token is valid and not revoked. uid = decoded_token['uid'] except tenant_mgt.TenantIdMismatchError: # Token belongs to a different tenant. pass except auth.RevokedIdTokenError: # Token revoked, inform the user to reauthenticate or signOut(). pass except auth.UserDisabledError: # Token belongs to a disabled user record. pass except auth.InvalidIdTokenError: # Token is invalid pass
Java
// Verify the ID token for a specific tenant while checking if the token is revoked. boolean checkRevoked = true; try { FirebaseToken token = tenantAuth.verifyIdToken(idToken, checkRevoked); System.out.println("Verified ID token for: " + token.getUid()); } catch (FirebaseAuthException e) { if ("id-token-revoked".equals(e.getErrorCode())) { // Token is revoked. Inform the user to re-authenticate or signOut() the user. } else { // Token is invalid } }
Lihat dokumentasi Admin SDK mengenai mengelola sesi untuk mempelajari lebih lanjut.
Mengontrol akses dengan klaim kustom
Admin SDK mendukung penentuan atribut khusus pada akun pengguna untuk tenant tertentu. Atribut ini memungkinkan Anda menerapkan berbagai strategi kontrol akses, seperti kontrol akses berbasis peran. Atribut ini dapat digunakan untuk memberi pengguna berbagai tingkat akses yang diterapkan oleh aturan keamanan aplikasi.
Untuk memulai, dapatkan instance TenantAwareAuth
untuk tenant yang sesuai:
Node.js
const tenantAuth = admin.auth().tenantManager().authForTenant('TENANT-ID');
Python
tenant_client = tenant_mgt.auth_for_tenant('TENANT-ID')
Java
TenantAwareFirebaseAuth tenantAuth = FirebaseAuth.getInstance().getTenantManager() .getAuthForTenant("TENANT-ID");
Klaim kustom dapat berisi data sensitif, sehingga hanya boleh ditetapkan dari lingkungan server dengan hak istimewa menggunakan Admin SDK.
Node.js
// Set admin privilege on the user corresponding to uid for a specific tenant.
tenantAuth.setCustomUserClaims(uid, {admin: true}).then(() => {
// The new custom claims will propagate to the user's ID token the
// next time a new one is issued.
});
Python
# Set admin privilege on the user corresponding to uid. tenant_client.set_custom_user_claims(uid, {'admin': True}) # The new custom claims will propagate to the user's ID token the # next time a new one is issued.
Java
// Set admin privilege on the user corresponding to uid in a specific tenant. Map<String, Object> claims = new HashMap<>(); claims.put("admin", true); tenantAuth.setCustomUserClaims(uid, claims); // The new custom claims will propagate to the user's ID token the // next time a new one is issued.
Atribut khusus yang baru ditetapkan akan muncul di atribut level teratas payload token saat pengguna login atau memperbarui token ID-nya pada sesi yang sudah ada. Pada contoh sebelumnya, token ID berisi klaim tambahan: {admin: true}
.
Setelah memverifikasi token ID dan mendekode payload-nya, klaim kustom tambahan dapat diperiksa untuk menerapkan kontrol akses.
Node.js
// Verify the ID token first.
tenantAuth.verifyIdToken(idToken).then((claims) => {
if (claims.admin === true) {
// Allow access to requested admin resource.
}
});
Python
# Verify the ID token first. claims = tenant_client.verify_id_token(id_token) if claims['admin'] is True: # Allow access to requested admin resource. pass
Java
// Verify the ID token first. FirebaseToken token = tenantAuth.verifyIdToken(idToken); if (Boolean.TRUE.equals(token.getClaims().get("admin"))) { //Allow access to requested admin resource. } // Verify the ID token first. FirebaseToken decoded = tenantAuth.verifyIdToken(idToken); if (Boolean.TRUE.equals(decoded.getClaims().get("admin"))) { // Allow access to requested admin resource. }
Klaim kustom bagi pengguna yang ada untuk tenant tertentu juga tersedia sebagai properti pada data pengguna.
Node.js
// Lookup the user associated with the specified uid.
tenantAuth.getUser(uid).then((userRecord) => {
// The claims can be accessed on the user record.
console.log(userRecord.customClaims.admin);
});
Python
# Lookup the user associated with the specified uid. user = tenant_client.get_user(uid) # The claims can be accessed on the user record. print(user.custom_claims.get('admin'))
Java
// Lookup the user associated with the specified uid in a specific tenant. UserRecord user = tenantAuth.getUser(uid); System.out.println(user.getCustomClaims().get("admin"));
Lihat dokumentasi Admin SDK tentang Klaim kustom untuk mempelajari lebih lanjut.
Membuat link tindakan email
Dengan menggunakan Identity Platform Client SDK, Anda dapat mengirim email tenant tertentu yang berisi link untuk reset sandi, verifikasi alamat email, dan login dengan email kepada pengguna. Email ini dikirim oleh Google dan memiliki kemampuan penyesuaian yang terbatas.
Dengan Admin SDK, Anda dapat membuat link ini secara terprogram dalam cakupan tenant tertentu.
Untuk memulai, dapatkan instance TenantAwareAuth
untuk tenant yang sesuai:
Node.js
const tenantAuth = admin.auth().tenantManager().authForTenant('TENANT-ID');
Python
tenant_client = tenant_mgt.auth_for_tenant('TENANT-ID')
Java
TenantAwareFirebaseAuth tenantAuth = FirebaseAuth.getInstance().getTenantManager() .getAuthForTenant("TENANT-ID");
Contoh berikut menunjukkan cara membuat link untuk memverifikasi email pengguna untuk tenant tertentu:
Node.js
const actionCodeSettings = {
// URL you want to redirect back to. The domain (www.example.com) for
// this URL must be whitelisted in the Cloud console.
url: 'https://www.example.com/checkout?cartId=1234',
// This must be true for email link sign-in.
handleCodeInApp: true,
iOS: {
bundleId: 'com.example.ios'
},
android: {
packageName: 'com.example.android',
installApp: true,
minimumVersion: '12'
},
// FDL custom domain.
dynamicLinkDomain: 'coolapp.page.link'
};
// Admin SDK API to generate the email verification link.
const userEmail = 'user@example.com';
tenantAuth.generateEmailVerificationLink(userEmail, actionCodeSettings)
.then((link) => {
// Construct email verification template, embed the link and send
// using custom SMTP server.
return sendCustomVerificationEmail(userEmail, displayName, link);
})
.catch((error) => {
// Some error occurred.
});
Python
action_code_settings = auth.ActionCodeSettings( url='https://www.example.com/checkout?cartId=1234', handle_code_in_app=True, ios_bundle_id='com.example.ios', android_package_name='com.example.android', android_install_app=True, android_minimum_version='12', # FDL custom domain. dynamic_link_domain='coolapp.page.link', ) email = 'user@example.com' link = tenant_client.generate_email_verification_link(email, action_code_settings) # Construct email from a template embedding the link, and send # using a custom SMTP server. send_custom_email(email, link)
Java
ActionCodeSettings actionCodeSettings = ActionCodeSettings.builder() // URL you want to redirect back to. The domain (www.example.com) for // this URL must be whitelisted in the GCP Console. .setUrl("https://www.example.com/checkout?cartId=1234") // This must be true for email link sign-in. .setHandleCodeInApp(true) .setIosBundleId("com.example.ios") .setAndroidPackageName("com.example.android") .setAndroidInstallApp(true) .setAndroidMinimumVersion("12") // FDL custom domain. .setDynamicLinkDomain("coolapp.page.link") .build(); String link = tenantAuth.generateEmailVerificationLink(email, actionCodeSettings); // Construct email verification template, embed the link and send // using custom SMTP server. sendCustomEmail(email, displayName, link);
Mekanisme serupa tersedia untuk membuat reset sandi dan link login berbasis email. Perhatikan bahwa saat membuat link tindakan email dalam konteks tenant, ID tenant harus diurai dari link dan ditetapkan pada instance Auth
klien sebelum kode dapat diterapkan.
const actionCodeUrl = firebase.auth.ActionCodeURL.parseLink(window.location.href);
// A one-time code, used to identify and verify a request.
const code = actionCodeUrl.code;
// The tenant ID being used to trigger the email action.
const tenantId = actionCodeUrl.tenantId;
auth.tenantId = tenantId;
// Apply the action code.
auth.applyActionCode(actionCode)
.then(() => {
// User's email is now verified.
})
.catch((error) => {
// Handle error.
});
Lihat Link tindakan email dalam dokumentasi Admin SDK untuk mempelajari lebih lanjut.
Pesan error
Tabel berikut mencantumkan pesan error umum yang mungkin Anda temui.
Kode error | Deskripsi dan Langkah Penyelesaian |
---|---|
auth/billing-not-enabled |
Fitur ini mengharuskan penagihan diaktifkan. |
auth/invalid-display-name |
Bidang displayName harus berupa string yang valid. |
auth/invalid-name |
Nama resource yang diberikan tidak valid. |
auth/invalid-page-token |
Token halaman harus berupa string yang tidak kosong dan valid. |
auth/invalid-project-id |
Project induk tidak valid. Project induk tidak mengaktifkannya, atau tidak mengaktifkan multi-tenancy. |
auth/invalid-tenant-id |
ID tenant harus berupa string yang tidak kosong dan valid. |
auth/mismatching-tenant-id |
ID tenant pengguna tidak cocok dengan ID tenant TenantAwareAuth saat ini.
|
auth/missing-display-name |
Resource yang dibuat atau diedit tidak memiliki nama tampilan yang valid. |
auth/insufficient-permission |
Pengguna tidak memiliki izin yang memadai untuk mengakses resource yang diminta atau untuk menjalankan operasi tenant tertentu. |
auth/quota-exceeded |
Kuota project untuk operasi yang ditentukan telah terlampaui. |
auth/tenant-not-found |
Tidak ada tenant yang sesuai dengan ID yang diberikan. |
auth/unsupported-tenant-operation |
Operasi ini tidak didukung dalam konteks multi-tenant. |
auth/invalid-testing-phone-number |
Nomor telepon pengujian yang tidak valid atau kode pengujian yang tidak valid diberikan. |
auth/test-phone-number-limit-exceeded |
Jumlah maksimum pasangan kode dan nomor telepon pengujian yang diizinkan telah terlampaui. |