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 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 memproses login pengguna 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 lanjutan, Anda juga dapat mem-build halaman login Anda sendiri dari awal. Opsi ini lebih kompleks, tetapi memberi Anda kontrol penuh atas alur autentikasi dan pengalaman pengguna.
Sebelum memulai
Aktifkan identitas eksternal, lalu pilih opsi Saya akan menyediakan UI saya sendiri selama penyiapan.
Menginstal library
Instal library gcip-iap
, firebase
, dan firebaseui
. Modul
gcip-iap
memisahkan komunikasi antara aplikasi,
IAP, dan Identity Platform Anda. Library firebase
dan firebaseui
menyediakan elemen 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 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:
- Update versi
firebase
danfirebaseui
dalam filepackage.json
Anda masing-masing ke v9.6.0+ dan v6.0.0+. - Perbarui pernyataan impor
firebase
sebagai 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 versi library yang dilokalkan, lihat petunjuk di GitHub.
Mengonfigurasi aplikasi
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 lain, lihat cuplikan kode di atas, atau dokumentasi FirebaseUI di GitHub.
Menetapkan kunci API
Konfigurasi standar 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 konsol Google Cloud.
Menentukan ID tenant
Konfigurasi memerlukan daftar tenant dan penyedia yang dapat digunakan pengguna untuk melakukan autentikasi.
Setiap tenant diidentifikasi dengan 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 penggantian jika tidak ada ID yang cocok yang ditemukan.
Mengonfigurasi penyedia tenant
Setiap tenant memiliki penyedianya sendiri; penyedia ini ditentukan di kolom signInOptions
:
tenantId1: {
signInOptions: [
// Options go here
]
}
Lihat Mengonfigurasi penyedia login dalam 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 memulai dengan memilih tenant dari daftar, lalu memasukkan nama pengguna dan sandinya. Dalam mode ID, pengguna memasukkan emailnya terlebih dahulu. Kemudian, sistem 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
disediakan 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. Ini dapat berupa ekspresi reguler (seperti
/@example\.com$/
) atau string domain (mis., 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
mengarahkan pengguna langsung ke penyedia.
Menyiapkan callback
Objek konfigurasi berisi kumpulan callback yang dipanggil di berbagai titik selama alur autentikasi. Hal ini juga memungkinkan Anda menyesuaikan UI. 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 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:
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
FirebaseUiHandler
untuk dirender dalam penampung HTML, dan teruskan elemenconfig
yang Anda buat ke instance tersebut.const configs = { // ... } const handler = new firebaseui.auth.FirebaseUiHandler( '#firebaseui-auth-container', configs);
Buat instance
Authentication
baru, teruskan pengendali ke instance tersebut, lalu 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 selanjutnya
- Pelajari cara mengakses resource non-Google secara terprogram.
- Pelajari cara mengelola sesi.
- Dapatkan pemahaman yang lebih mendalam tentang cara kerja identitas eksternal dengan IAP.