Untuk menggunakan identitas eksternal dengan Identity-Aware Proxy (IAP), aplikasi Anda memerlukan halaman login. IAP akan mengalihkan pengguna ke halaman ini untuk melakukan autentikasi sebelum mereka dapat mengakses resource yang aman.
Artikel ini menunjukkan cara membuat halaman autentikasi menggunakan FirebaseUI, library JavaScript open source. FirebaseUI menyediakan elemen yang dapat disesuaikan yang membantu mengurangi kode boilerplate, dan menangani alur untuk membuat pengguna login dengan berbagai penyedia identitas.
Untuk memulai lebih cepat, izinkan IAP menghosting UI untuk Anda. Hal ini memungkinkan Anda mencoba identitas eksternal tanpa menulis kode tambahan. Untuk skenario yang lebih canggih, Anda juga dapat membuat halaman login sendiri dari awal. Opsi ini lebih kompleks, tetapi memberi Anda kontrol penuh atas alur autentikasi dan pengalaman pengguna.
Sebelum memulai
Aktifkan identitas eksternal, dan pilih opsi I'll provide my own UI selama penyiapan.
Menginstal library
Instal library gcip-iap, firebase, dan firebaseui. Modul gcip-iap mengabstraksi komunikasi antara aplikasi Anda, IAP, dan Identity Platform. Library firebase dan firebaseui menyediakan blok penyusun untuk UI autentikasi Anda.
npm install firebase --save
npm install firebaseui --save
npm install gcip-iap --save
Perhatikan bahwa modul gcip-iap tidak tersedia menggunakan CDN.
Kemudian, Anda dapat import modul dalam file sumber. Gunakan impor yang benar untuk versi SDK Anda:
gcip-iap v0.1.4 atau yang lebih lama
// Import firebase modules.
import * as firebase from "firebase/app";
import "firebase/auth";
// Import firebaseui module.
import * as firebaseui from 'firebaseui'
// Import gcip-iap module.
import * as ciap from 'gcip-iap';
gcip-iap v1.0.0 atau yang lebih baru
Mulai dari versi v1.0.0, gcip-iap memerlukan dependensi peer firebase v9 atau yang lebih baru.
Jika Anda bermigrasi ke gcip-iap v1.0.0 atau yang lebih baru, selesaikan tindakan berikut:
- Perbarui versi
firebasedanfirebaseuidi filepackage.jsonke v9.6.0+ dan v6.0.0+. - Perbarui pernyataan impor
firebasesebagai berikut:
// Import firebase modules.
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
// Import firebaseui module.
import * as firebaseui from 'firebaseui'
// Import gcip-iap module.
Tidak diperlukan perubahan kode tambahan.
Untuk opsi penginstalan tambahan, termasuk menggunakan library versi yang dilokalkan, lihat petunjuk di GitHub.
Mengonfigurasi aplikasi Anda
FirebaseUI menggunakan objek konfigurasi yang menentukan tenant dan penyedia yang akan digunakan untuk autentikasi. Konfigurasi lengkap bisa sangat panjang, dan mungkin terlihat seperti ini:
// The project configuration.
const configs = {
// Configuration for project identified by API key API_KEY1.
API_KEY1: {
authDomain: 'project-id1.firebaseapp.com',
// Decide whether to ask user for identifier to figure out
// what tenant to select or whether to present all the tenants to select from.
displayMode: 'optionFirst', // Or identifierFirst
// The terms of service URL and privacy policy URL for the page
// where the user select tenant or enter email for tenant/provider
// matching.
tosUrl: 'http://localhost/tos',
privacyPolicyUrl: 'http://localhost/privacypolicy',
callbacks: {
// The callback to trigger when the selection tenant page
// or enter email for tenant matching page is shown.
selectTenantUiShown: () => {
// Show title and additional display info.
},
// The callback to trigger when the sign-in page
// is shown.
signInUiShown: (tenantId) => {
// Show tenant title and additional display info.
},
beforeSignInSuccess: (user) => {
// Do additional processing on user before sign-in is
// complete.
return Promise.resolve(user);
}
},
tenants: {
// Tenant configuration for tenant ID tenantId1.
tenantId1: {
// Full label, display name, button color and icon URL of the
// tenant selection button. Only needed if you are
// using the option first option.
fullLabel: 'ACME Portal',
displayName: 'ACME',
buttonColor: '#2F2F2F',
iconUrl: '<icon-url-of-sign-in-button>',
// Sign-in providers enabled for tenantId1.
signInOptions: [
// Microsoft sign-in.
{
provider: 'microsoft.com',
providerName: 'Microsoft',
buttonColor: '#2F2F2F',
iconUrl: '<icon-url-of-sign-in-button>',
loginHintKey: 'login_hint'
},
// Email/password sign-in.
{
provider: 'password',
// Do not require display name on sign up.
requireDisplayName: false,
disableSignUp: {
// Disable user from signing up with email providers.
status: true,
adminEmail: 'admin@example.com',
helpLink: 'https://www.example.com/trouble_signing_in'
}
},
// SAML provider. (multiple SAML providers can be passed)
{
provider: 'saml.my-provider1',
providerName: 'SAML provider',
fullLabel: 'Employee Login',
buttonColor: '#4666FF',
iconUrl: 'https://www.example.com/photos/my_idp/saml.png'
},
],
// If there is only one sign-in provider eligible for the user,
// whether to show the provider selection page.
immediateFederatedRedirect: true,
signInFlow: 'redirect', // Or popup
// The terms of service URL and privacy policy URL for the sign-in page
// specific to each tenant.
tosUrl: 'http://localhost/tenant1/tos',
privacyPolicyUrl: 'http://localhost/tenant1/privacypolicy'
},
// Tenant configuration for tenant ID tenantId2.
tenantId2: {
fullLabel: 'OCP Portal',
displayName: 'OCP',
buttonColor: '#2F2F2F',
iconUrl: '<icon-url-of-sign-in-button>',
// Tenant2 supports a SAML, OIDC and Email/password sign-in.
signInOptions: [
// Email/password sign-in.
{
provider: firebase.auth.EmailAuthProvider.PROVIDER_ID,
// Do not require display name on sign up.
requireDisplayName: false
},
// SAML provider. (multiple SAML providers can be passed)
{
provider: 'saml.my-provider2',
providerName: 'SAML provider',
fullLabel: 'Contractor Portal',
buttonColor: '#4666FF',
iconUrl: 'https://www.example.com/photos/my_idp/saml.png'
},
// OIDC provider. (multiple OIDC providers can be passed)
{
provider: 'oidc.my-provider1',
providerName: 'OIDC provider',
buttonColor: '#4666FF',
iconUrl: 'https://www.example.com/photos/my_idp/oidc.png'
},
],
},
// Tenant configuration for tenant ID tenantId3.
tenantId3: {
fullLabel: 'Tenant3 Portal',
displayName: 'Tenant3',
buttonColor: '#007bff',
iconUrl: '<icon-url-of-sign-in-button>',
// Tenant3 supports a Google and Email/password sign-in.
signInOptions: [
// Email/password sign-in.
{
provider: firebase.auth.EmailAuthProvider.PROVIDER_ID,
// Do not require display name on sign up.
requireDisplayName: false
},
// Google provider.
{
provider: 'google.com',
scopes: ['scope1', 'scope2', 'https://example.com/scope3'],
loginHintKey: 'login_hint',
customParameters: {
prompt: 'consent',
},
},
],
// Sets the adminRestrictedOperation configuration for providers
// including federated, email/password, email link and phone number.
adminRestrictedOperation: {
status: true,
adminEmail: 'admin@example.com',
helpLink: 'https://www.example.com/trouble_signing_in'
}
},
},
},
};
Bagian berikut memberikan panduan tentang cara mengonfigurasi beberapa kolom khusus untuk IAP. Untuk contoh cara menetapkan kolom lainnya, lihat cuplikan kode di atas, atau dokumentasi FirebaseUI di GitHub.
Menetapkan kunci API
Konfigurasi umum dimulai dengan kunci API untuk project Anda:
// The project configuration.
const configs = {
// Configuration for API_KEY.
API_KEY: {
// Config goes here
}
}
Dalam sebagian besar kasus, Anda hanya perlu menentukan satu kunci API. Namun, jika ingin menggunakan satu URL autentikasi di beberapa project, Anda dapat menyertakan beberapa kunci API:
const configs = {
API_KEY1: {
// Config goes here
},
API_KEY2: {
// Config goes here
},
}
Mendapatkan domain autentikasi
Tetapkan kolom authdomain ke domain yang disediakan untuk memfasilitasi login gabungan. Anda dapat mengambil kolom ini dari halaman
Identity Platform di Google Cloud konsol.
Menentukan ID tenant
Konfigurasi memerlukan daftar tenant dan penyedia yang dapat digunakan pengguna untuk melakukan autentikasi.
Setiap tenant diidentifikasi berdasarkan ID-nya. Jika Anda menggunakan autentikasi tingkat project (tanpa tenant), gunakan ID _ khusus sebagai kunci API. Contoh:
const configs = {
// Configuration for project identified by API key API_KEY1.
API_KEY1: {
tenants: {
// Project-level IdPs flow.
_: {
// Tenant config goes here
},
// Single tenant flow.
1036546636501: {
// Tenant config goes here
}
}
}
}
Anda juga dapat menentukan konfigurasi tenant karakter pengganti menggunakan operator *.
Tenant ini digunakan sebagai pengganti jika tidak ada ID yang cocok ditemukan.
Mengonfigurasi penyedia tenant
Setiap tenant memiliki penyedia sendiri; penyedia ini ditentukan di kolom signInOptions:
tenantId1: {
signInOptions: [
// Options go here
]
}
Lihat Mengonfigurasi penyedia login di dokumentasi FirebaseUI untuk mempelajari cara mengonfigurasi penyedia.
Selain langkah-langkah yang diuraikan dalam dokumentasi FirebaseUI, ada beberapa kolom khusus untuk IAP yang bergantung pada mode pemilihan tenant yang Anda pilih. Lihat bagian berikutnya untuk mengetahui informasi selengkapnya tentang kolom ini.
Memilih mode pemilihan tenant
Pengguna dapat memilih tenant dengan dua cara: mode opsi pertama, atau mode ID pertama.
Dalam mode opsi, pengguna mulai dengan memilih tenant dari daftar, lalu memasukkan nama pengguna dan sandi. Dalam mode ID, pengguna memasukkan email terlebih dahulu. Sistem kemudian akan otomatis memilih tenant pertama dengan penyedia identitas yang cocok dengan domain email.
Untuk menggunakan mode opsi, tetapkan displayMode ke optionFirst. Kemudian, Anda harus memberikan informasi konfigurasi untuk setiap tombol tenant, termasuk displayName, buttonColor, dan iconUrl. fullLabel opsional juga dapat diberikan untuk mengganti seluruh label tombol, bukan hanya nama tampilan.
Berikut adalah contoh tenant yang dikonfigurasi untuk menggunakan mode opsi:
tenantId1: {
fullLabel: 'ACME Portal',
displayName: 'ACME',
buttonColor: '#2F2F2F',
iconUrl: '<icon-url-of-sign-in-button>',
// ...
Untuk menggunakan mode ID, setiap opsi login harus menentukan kolom hd yang menunjukkan domain yang didukungnya. Kolom ini dapat berupa regex (seperti /@example\.com$/) atau string domain (misalnya, example.com).
Kode di bawah menunjukkan tenant yang dikonfigurasi untuk menggunakan mode ID:
tenantId1: {
signInOptions: [
// Email/password sign-in.
{
hd: 'acme.com', // using regex: /@acme\.com$/
// ...
},
Mengaktifkan pengalihan langsung
Jika aplikasi Anda hanya mendukung satu penyedia identitas, menetapkan immediateFederatedRedirect ke true akan melewati UI login dan mengalihkan pengguna langsung ke penyedia.
Menyiapkan callback
Objek konfigurasi berisi kumpulan callback yang dipanggil pada berbagai titik selama alur autentikasi. Hal ini memungkinkan Anda menyesuaikan UI lebih lanjut. Hook berikut tersedia:
selectTenantUiShown() |
Dipicu saat UI untuk memilih tenant ditampilkan. Gunakan ini jika Anda ingin mengubah UI dengan judul atau tema yang disesuaikan. |
signInUiShown(tenantId) |
Dipicu saat tenant dipilih dan UI untuk pengguna memasukkan kredensialnya ditampilkan. Gunakan ini jika Anda ingin mengubah UI dengan a judul atau tema yang disesuaikan. |
beforeSignInSuccess(user) |
Dipicu sebelum login selesai. Gunakan ini untuk mengubah pengguna yang login sebelum mengalihkan kembali ke resource IAP. |
Contoh kode berikut menunjukkan cara menerapkan callback ini:
callbacks: {
selectTenantUiShown: () => {
// Show info of the IAP resource.
showUiTitle(
'Select your employer to access your Health Benefits');
},
signInUiShown: (tenantId) => {
// Show tenant title and additional display info.
const tenantName = getTenantNameFromId(tenantId);
showUiTitle(`Sign in to access your ${tenantName} Health Benefits`);
},
beforeSignInSuccess: (user) => {
// Do additional processing on user before sign-in is
// complete.
// For example update the user profile.
return user.updateProfile({
photoURL: 'https://example.com/profile/1234/photo.png',
}).then(function() {
// To reflect updated photoURL in the ID token, force token
// refresh.
return user.getIdToken(true);
}).then(function() {
return user;
});
}
}
Melakukan inisialisasi library
Setelah membuat objek konfigurasi, ikuti langkah-langkah berikut untuk melakukan inisialisasi library di halaman autentikasi Anda:
Buat penampung HTML untuk merender UI.
<!DOCTYPE html> <html> <head>...</head> <body> <!-- The surrounding HTML is left untouched by FirebaseUI. Your app may use that space for branding, controls and other customizations.--> <h1>Welcome to My Awesome App</h1> <div id="firebaseui-auth-container"></div> </body> </html>Buat instance
FirebaseUiHandleruntuk dirender di penampung HTML, dan teruskan elemenconfigyang Anda buat ke dalamnya.const configs = { // ... } const handler = new firebaseui.auth.FirebaseUiHandler( '#firebaseui-auth-container', configs);Buat instance
Authenticationbaru, teruskan pengendali ke dalamnya, dan panggilstart().const ciapInstance = new ciap.Authentication(handler); ciapInstance.start();
Deploy aplikasi Anda dan buka halaman autentikasi. UI login yang berisi tenant dan penyedia Anda akan muncul.
Langkah berikutnya
- Pelajari cara mengakses resource non-Google secara terprogram.
- Pelajari cara mengelola sesi.
- Dapatkan pemahaman yang lebih mendalam tentang cara kerja identitas eksternal dengan IAP.