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 meliputi:
Pengelolaan pengguna: Buat, perbarui, hapus, dan cantumkan pengguna untuk tenant tertentu.
Verifikasi identitas: Mengidentifikasi pengguna aplikasi untuk membatasi akses ke resource di server Anda sendiri.
Mengimpor pengguna: Memigrasikan pengguna dari sistem autentikasi eksternal atau project atau tenant Identity Platform lain.
Kontrol akses dengan klaim kustom: Tentukan atribut kustom di akun pengguna untuk tenant tertentu dan terapkan berbagai strategi kontrol akses, seperti kontrol akses berbasis peran.
Pengelolaan sesi pengguna: Mencabut token refresh pengguna untuk tenant tertentu.
Link tindakan email: Buat link email yang disesuaikan untuk reset sandi, login dengan link email, dan verifikasi email bagi pengguna tenant tertentu.
Pengelolaan tenant: Buat, buat daftar, dapatkan, perbarui, hapus tenant untuk project Identity Platform tertentu.
Mengelola penyedia OIDC dan SAML di tenant: Mengelola konfigurasi OIDC dan SAML secara terprogram di tenant tertentu.
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 dalam 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 | KonsolGoogle Cloud | Admin SDK |
|---|---|---|
| OIDC | ||
| SAML | ||
| Sosial | ||
| Telepon | ||
| Autentikasi multi-faktor | ||
| Anonim |
Pengelolaan tenant
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 serangkaian penggunanya sendiri.
Operasi pengelolaan konfigurasi tenant (CRUD) tersedia dari instance project induk menggunakan admin.auth().tenantManager().
Konfigurasi tenant memberikan informasi tentang tenant, seperti nama tampilannya, ID tenant, dan konfigurasi autentikasi email.
Semua setelan lainnya (seperti domain yang diizinkan dan URI pengalihan yang diautentikasi) tenant diwarisi dari project induk. Setelan 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-nya).
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('Retrieved 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 sudah ada, promise yang ditampilkan akan ditolak dengan error auth/tenant-not-found.
Berhati-hatilah agar tidak tertukar antara instance Tenant dan 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 konteks yang berbeda. Untuk Auth, konteksnya berada di tingkat project induk.
Untuk TenantAwareAuth, konteksnya berada di tingkat tenant (tenant ditentukan oleh ID tenant). Metode getTenant() akan diselesaikan dengan informasi dasar
penyewa (seperti ID penyewa, nama tampilan, dan setelan penyedia email),
tetapi untuk memanggil API di penyewa tersebut, Anda harus 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 berikut:
| Properti | Jenis | Deskripsi |
|---|---|---|
displayName |
string
|
Nama tampilan tenant. Nama 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 dengan email. Hal ini mencakup apakah penyedia email diaktifkan, dan apakah sandi diperlukan untuk login dengan email. Jika tidak diperlukan, login email dapat dilakukan dengan sandi atau menggunakan login dengan link email. |
multiFactorConfig |
{
state: 'DISABLED' | 'ENABLED',
factorIds: string[]
}
|
Apakah
autentikasi multi-faktor
diaktifkan untuk tenant, dan jenis faktor apa yang diizinkan. Saat ini, satu-satunya ID faktor yang didukung adalah phone.
|
testPhoneNumbers |
{
string: string
}
|
Peta nomor telepon dan kode autentikasi multi-faktor terkait untuk mendaftar
untuk tujuan pengujian.
Maksimum 10 entri yang diizinkan. Untuk menghapus semua nomor telepon pengujian, tetapkan
kolom ini ke null.
|
Metode ini akan 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 dengan 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 diberikan bukan milik tenant yang sudah 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 dilakukan.
Jika tenantId yang diberikan bukan milik tenant yang sudah ada, promise yang ditampilkan akan ditolak dengan error auth/tenant-not-found.
Mencantumkan tenant
Gunakan metode listTenants() untuk mencantumkan 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 mencantumkan batch tenant berikutnya. Setelah semua tenant sudah tercantum, tidak ada pageToken yang ditampilkan.
Jika kolom maxResults tidak ditentukan, nilai defaultnya adalah 1.000 tenant per batch.
Angka ini juga menunjukkan jumlah maksimum penyewa yang diizinkan untuk dicantumkan pada satu waktu.
Setiap nilai yang lebih besar daripada nilai maksimum akan menampilkan error argumen.
Jika pageToken tidak ditentukan, metode akan mencantumkan tenant dari awal.
Mengelola penyedia SAML dan OIDC secara terprogram
Admin SDK menyediakan API untuk mengelola konfigurasi penyedia OpenID Connect (OIDC) dan Security Assertion Markup Language (SAML) 2.0 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 bagi 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 penyedia mereka:
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());
Mencantumkan penyedia
Kode berikut menunjukkan cara mencantumkan 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 dengan cara yang sama seperti penyedia OIDC tingkat project, kecuali penyedia OIDC dapat dikelola dari instance TenantAwareAuth yang sesuai, bukan dari instance tingkat 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 mencantumkan 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 berdasarkan 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 bagi tenant tertentu.
Saat membuat pengguna baru, pemberian uid bersifat opsional; jika tidak ditentukan,
Identity Platform akan menyediakan uid 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 mengubah 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-nya:
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 masih 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(); }
Lihat dokumentasi Admin SDK tentang 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 lain, 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) dan klaim kustom 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()); }
Semua pengguna yang diimpor akan memiliki tenantId yang ditetapkan ke tenantAuth.tenantId.
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
Saat aplikasi klien Identity Platform berkomunikasi dengan server backend kustom, pengguna yang saat ini login harus diidentifikasi di server tersebut. Hal ini dapat dilakukan dengan aman dengan mengirimkan token ID pengguna setelah berhasil login menggunakan koneksi yang aman ke server Anda. Server kemudian dapat memverifikasi integritas dan keaslian token ID.
Admin SDK memiliki metode bawaan untuk memverifikasi dan mendekode token ID untuk tenant tertentu.
Setelah berhasil membuat pengguna login 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 tertentu 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. Karena ID tenant mungkin tidak diketahui sebelumnya dalam kasus ini, token ID dapat diverifikasi di tingkat 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()); }
Lihat dokumentasi Admin SDK tentang memverifikasi token ID untuk mempelajari lebih lanjut.
Mengelola sesi pengguna
Sesi Identity Platform berdurasi panjang. Setiap kali pengguna login, kredensial pengguna tersebut diverifikasi di server Identity Platform, lalu ditukar dengan token ID yang berlaku singkat dan token refresh yang berlaku lama. Token ID berlaku selama satu jam. Token refresh tidak pernah habis masa berlakunya, kecuali jika pengguna dinonaktifkan, dihapus, atau mengalami perubahan besar pada akun (seperti pembaruan email atau sandi).
Terkadang, token refresh pengguna mungkin perlu dicabut karena alasan keamanan, seperti pengguna melaporkan perangkatnya hilang atau dicuri, penemuan kerentanan umum dalam aplikasi, atau kebocoran token aktif dalam skala luas. Admin SDK menyediakan API untuk mencabut semua token refresh yang dikeluarkan untuk pengguna tertentu 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 menentukan 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(f'Tokens revoked at: {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 pengguna melakukan autentikasi ulang. Namun, token ID yang ada akan tetap aktif hingga waktu habis masa berlakunya (satu jam).
Anda dapat memverifikasi bahwa token ID valid yang belum habis masa berlakunya tidak dicabut dengan menentukan
parameter checkRevoked opsional; hal ini 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 tentang mengelola sesi untuk mempelajari lebih lanjut.
Mengontrol akses dengan klaim kustom
Admin SDK mendukung penetapan atribut kustom pada akun pengguna untuk tenant tertentu. Atribut ini memungkinkan Anda menerapkan berbagai strategi kontrol akses, seperti kontrol akses berbasis peran. Atribut 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, jadi sebaiknya hanya 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 kustom yang baru ditetapkan akan muncul di atribut tingkat teratas payload token saat pengguna login atau me-refresh token ID mereka pada sesi yang ada. Dalam 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 untuk pengguna yang sudah 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 SDK Klien Identity Platform, Anda dapat mengirim email kepada pengguna tenant tertentu yang berisi link yang dapat mereka gunakan untuk mereset sandi, memverifikasi alamat email, dan login berbasis email. 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 link 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 memerlukan pengaktifan penagihan. |
auth/invalid-display-name |
Kolom displayName harus berupa string yang valid. |
auth/invalid-name |
Nama resource yang diberikan tidak valid. |
auth/invalid-page-token |
Token halaman harus berupa string tidak kosong yang valid. |
auth/invalid-project-id |
Project induk tidak valid. Project induk tidak, atau tidak mengaktifkan multi-tenancy. |
auth/invalid-tenant-id |
ID tenant harus berupa string tidak kosong yang 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 telah diberikan. |
auth/test-phone-number-limit-exceeded |
Jumlah maksimum pasangan kode dan nomor telepon pengujian yang diizinkan telah terlampaui. |