Creating a sign-in page with FirebaseUI

To use external identities with Identity-Aware Proxy (IAP), your app needs a sign-in page. IAP will redirect users to this page to authenticate before they can access secure resources.

This article shows you how to build an authentication page using FirebaseUI, an open-source JavaScript library. FirebaseUI provides customizable elements that help reduce boilerplate code, and handles the flows for signing in users with a wide range of identity providers.

To get started faster, let IAP host the UI for you. This lets you try external identities without writing any additional code. For more advanced scenarios, you can also build your own sign-in page from scratch. This option is more complex, but gives you full control over the authentication flow and user experience.

Before you begin

Enable external identities, and select the I'll provide my own UI option during setup.

Installing the libraries

Install the gcip-iap, firebase, and firebaseui libraries. The gcip-iap module abstracts communications between your app, IAP, and Identity Platform. The firebase and firebaseui libraries provide the building blocks for your authentication UI.

npm install firebase --save
npm install firebaseui --save
npm install gcip-iap --save

Note that the gcip-iap module is not available using CDN.

You can then import the modules in your source files. Use the correct imports for your SDK version:

gcip-iap v0.1.4 or earlier

// 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 or later

Starting with version v1.0.0, gcip-iap requires the firebase v9 peer dependency or greater. If you are migrating to gcip-iap v1.0.0 or above, complete the following actions:

  • Update the firebase and firebaseui versions in your package.json file to v9.6.0+ and v6.0.0+ respectively.
  • Update the firebase import statements as follows:
// Import firebase modules.
importfirebase from'firebase/compat/app';
import'firebase/compat/auth';
// Import firebaseui module.
import* as firebaseui from'firebaseui'
// Import gcip-iap module.

No additional code changes are needed.

For additional installation options, including using localized versions of the libraries, refer to the instructions on GitHub.

Configuring your application

FirebaseUI uses a configuration object that specifies the tenants and providers to use for authentication. A full configuration can be very long, and might look something like this:

//Theprojectconfiguration.
constconfigs={
//ConfigurationforprojectidentifiedbyAPIkeyAPI_KEY1.
API_KEY1:{
authDomain:'project-id1.firebaseapp.com',
//Decidewhethertoaskuserforidentifiertofigureout
//whattenanttoselectorwhethertopresentallthetenantstoselectfrom.
displayMode:'optionFirst',//OridentifierFirst
//ThetermsofserviceURLandprivacypolicyURLforthepage
//wheretheuserselecttenantorenteremailfortenant/provider
//matching.
tosUrl:'http://localhost/tos',
privacyPolicyUrl:'http://localhost/privacypolicy',
callbacks:{
//Thecallbacktotriggerwhentheselectiontenantpage
//orenteremailfortenantmatchingpageisshown.
selectTenantUiShown:()=>{
//Showtitleandadditionaldisplayinfo.
},
//Thecallbacktotriggerwhenthesign-inpage
//isshown.
signInUiShown:(tenantId)=>{
//Showtenanttitleandadditionaldisplayinfo.
},
beforeSignInSuccess:(user)=>{
//Doadditionalprocessingonuserbeforesign-inis
//complete.
returnPromise.resolve(user);
}
},
tenants:{
//TenantconfigurationfortenantIDtenantId1.
tenantId1:{
//Fulllabel,displayname,buttoncolorandiconURLofthe
//tenantselectionbutton.Onlyneededifyouare
//usingtheoptionfirstoption.
fullLabel:'ACME Portal',
displayName:'ACME',
buttonColor:'#2F2F2F',
iconUrl:'<icon-url-of-sign-in-button>',
//Sign-inprovidersenabledfortenantId1.
signInOptions:[
//Microsoftsign-in.
{
provider:'microsoft.com',
providerName:'Microsoft',
buttonColor:'#2F2F2F',
iconUrl:'<icon-url-of-sign-in-button>',
loginHintKey:'login_hint'
},
//Email/passwordsign-in.
{
provider:'password',
//Donotrequiredisplaynameonsignup.
requireDisplayName:false,
disableSignUp:{
//Disableuserfromsigningupwithemailproviders.
status:true,
adminEmail:'admin@example.com',
helpLink:'https://www.example.com/trouble_signing_in'
}
},
//SAMLprovider.(multipleSAMLproviderscanbepassed)
{
provider:'saml.my-provider1',
providerName:'SAML provider',
fullLabel:'Employee Login',
buttonColor:'#4666FF',
iconUrl:'https://www.example.com/photos/my_idp/saml.png'
},
],
//Ifthereisonlyonesign-inprovidereligiblefortheuser,
//whethertoshowtheproviderselectionpage.
immediateFederatedRedirect:true,
signInFlow:'redirect',//Orpopup
//ThetermsofserviceURLandprivacypolicyURLforthesign-inpage
//specifictoeachtenant.
tosUrl:'http://localhost/tenant1/tos',
privacyPolicyUrl:'http://localhost/tenant1/privacypolicy'
},
//TenantconfigurationfortenantIDtenantId2.
tenantId2:{
fullLabel:'OCP Portal',
displayName:'OCP',
buttonColor:'#2F2F2F',
iconUrl:'<icon-url-of-sign-in-button>',
//Tenant2supportsaSAML,OIDCandEmail/passwordsign-in.
signInOptions:[
//Email/passwordsign-in.
{
provider:firebase.auth.EmailAuthProvider.PROVIDER_ID,
//Donotrequiredisplaynameonsignup.
requireDisplayName:false
},
//SAMLprovider.(multipleSAMLproviderscanbepassed)
{
provider:'saml.my-provider2',
providerName:'SAML provider',
fullLabel:'Contractor Portal',
buttonColor:'#4666FF',
iconUrl:'https://www.example.com/photos/my_idp/saml.png'
},
//OIDCprovider.(multipleOIDCproviderscanbepassed)
{
provider:'oidc.my-provider1',
providerName:'OIDC provider',
buttonColor:'#4666FF',
iconUrl:'https://www.example.com/photos/my_idp/oidc.png'
},
],
},
//TenantconfigurationfortenantIDtenantId3.
tenantId3:{
fullLabel:'Tenant3 Portal',
displayName:'Tenant3',
buttonColor:'#007bff',
iconUrl:'<icon-url-of-sign-in-button>',
//Tenant3supportsaGoogleandEmail/passwordsign-in.
signInOptions:[
//Email/passwordsign-in.
{
provider:firebase.auth.EmailAuthProvider.PROVIDER_ID,
//Donotrequiredisplaynameonsignup.
requireDisplayName:false
},
//Googleprovider.
{
provider:'google.com',
scopes:['scope1','scope2','https://example.com/scope3'],
loginHintKey:'login_hint',
customParameters:{
prompt:'consent',
},
},
],
//SetstheadminRestrictedOperationconfigurationforproviders
//includingfederated,email/password,emaillinkandphonenumber.
adminRestrictedOperation:{
status:true,
adminEmail:'admin@example.com',
helpLink:'https://www.example.com/trouble_signing_in'
}
},
},
},
};

The following sections provide guidance on how to configure some of the fields specific to IAP. For examples on setting other fields, see the code snippet above, or the FirebaseUI documentation on GitHub.

Setting the API key

A typical configuration begins with an API key for your project:

//Theprojectconfiguration.
constconfigs={
//ConfigurationforAPI_KEY.
API_KEY:{
//Configgoeshere
}
}

In most cases, you only need to specify a single API key. However, if you want to use a single authentication URL across multiple projects, you can include multiple API keys:

constconfigs={
API_KEY1:{
//Configgoeshere
},
API_KEY2:{
//Configgoeshere
},
}

Getting the authentication domain

Set the authdomain field to the domain provisioned to facilitate federated sign-in. You can retrieve this field from the Identity Platform page in the Google Cloud console.

Specifying tenants IDs

A configuration requires a list of tenants and providers that users can authenticate with.

Each tenant is identified by its ID. If you're using project-level authentication (no tenants), use the special _ identifier as an API key instead. For example:

constconfigs={
//ConfigurationforprojectidentifiedbyAPIkeyAPI_KEY1.
API_KEY1:{
tenants:{
//Project-levelIdPsflow.
_:{
//Tenantconfiggoeshere
},
//Singletenantflow.
1036546636501:{
//Tenantconfiggoeshere
}
}
}
}

You can also specify a wildcard tenant configuration using the * operator. This tenant is used as a fallback if no matching ID is found.

Configuring tenant providers

Each tenant has its own providers; these are specified in the signInOptions field:

tenantId1:{
signInOptions:[
 // Options go here
]
}

See Configuring sign-in providers in the FirebaseUI documentation to learn how to configure providers.

In addition to the steps outlined in the FirebaseUI documentation, there are several fields specific to IAP that depend on the tenant selection mode you choose. See the next section for more information on these fields.

Choosing a tenant selection mode

Users can select a tenant in two ways: options-first mode, or identifier-first mode.

In options mode, the user begins by selecting a tenant from a list, then enters their username and password. In identifier mode, the user enters their email first. The system then automatically selects the first tenant with an identity provider matching the email's domain.

To use options mode, set displayMode to optionFirst. You'll then need to provide configuration information for each tenant's button, including displayName, buttonColor, and iconUrl. An optional fullLabel can also be provided to override the entire button label instead of just the display name.

The following is an example of a tenant configured to use options mode:

tenantId1: {
 fullLabel: 'ACME Portal',
 displayName: 'ACME',
 buttonColor: '#2F2F2F',
 iconUrl: '<icon-url-of-sign-in-button>',
 // ...

To use identifier mode, each sign-in option must specify an hd field indicating what domain it supports. This can be either a regex (such as /@example\.com$/) or the domain string (e.g., example.com).

The code below shows a tenant configured to use identifier mode:

tenantId1:{
signInOptions:[
//Email/passwordsign-in.
{
hd:'acme.com',//usingregex:/@acme\.com$/
//...
},

Enabling immediate redirect

If your app only supports a single identity provider, setting immediateFederatedRedirect to true will skip the sign-in UI and redirect the user directly to the provider.

Setting up callbacks

The configuration object contains a set of callbacks that are invoked at various points during the authentication flow. This lets you additionally customize the UI. The following hooks are available:

selectTenantUiShown() Triggered when the UI to select a tenant is shown. Use this if you want to modify the UI with a customized title or theme.
signInUiShown(tenantId) Triggered when a tenant is selected and the UI for the user to enter their credentials is shown. Use this if you want to modify the UI with a customized title or theme.
beforeSignInSuccess(user) Triggered before sign-in completes. Use this to modify a signed in user before redirecting back to the IAP resource.

The following example code shows how you might implement these callbacks:

callbacks:{
selectTenantUiShown:()=>{
//ShowinfooftheIAPresource.
showUiTitle(
'Select your employer to access your Health Benefits');
},
signInUiShown:(tenantId)=>{
//Showtenanttitleandadditionaldisplayinfo.
consttenantName=getTenantNameFromId(tenantId);
showUiTitle(`Sign in to access your ${tenantName} Health Benefits`);
},
beforeSignInSuccess:(user)=>{
//Doadditionalprocessingonuserbeforesign-inis
//complete.
//Forexampleupdatetheuserprofile.
returnuser.updateProfile({
photoURL:'https://example.com/profile/1234/photo.png',
}).then(function(){
//ToreflectupdatedphotoURLintheIDtoken,forcetoken
//refresh.
returnuser.getIdToken(true);
}).then(function(){
returnuser;
});
}
}

Initializing the library

Once you've created a configuration object, follow these steps to initialize the library on your authentication page:

  1. Create an HTML container to render the UI in.

    <!DOCTYPE html>
    <html>
    <head>...</head>
    <body>
    <!--ThesurroundingHTMLisleftuntouchedbyFirebaseUI.
    Yourappmayusethatspaceforbranding,controlsandother
    customizations.-->
    <h1>WelcometoMyAwesomeApp</h1>
    <divid="firebaseui-auth-container"></div>
    </body>
    </html>
    
  2. Create a FirebaseUiHandler instance to render in the HTML container, and pass the config element you created to it.

    constconfigs={
    //...
    }
    consthandler=newfirebaseui.auth.FirebaseUiHandler(
    '#firebaseui-auth-container',configs);
    
  3. Create a new Authentication instance, pass the handler to it, and call start().

    constciapInstance=newciap.Authentication(handler);
    ciapInstance.start();
    

Deploy your application and navigate to the authentication page. A sign-in UI containing your tenants and providers should appear.

What's next

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025年12月30日 UTC.