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 UIoption 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 
 . 
 import 
  
 firebase 
 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:

  // 
  
 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' 
  
 } 
  
 }, 
  
 }, 
  
 }, 
 }; 
 

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:

  // 
  
 The 
  
 project 
  
 configuration 
 . 
 const 
  
 configs 
  
 = 
  
 { 
  
 // 
  
 Configuration 
  
 for 
  
 API_KEY 
 . 
  
 API_KEY 
 : 
  
 { 
  
 // 
  
 Config 
  
 goes 
  
 here 
  
 } 
 } 
 

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:

  const 
  
 configs 
  
 = 
  
 { 
  
 API_KEY1 
 : 
  
 { 
  
 // 
  
 Config 
  
 goes 
  
 here 
  
 }, 
  
 API_KEY2 
 : 
  
 { 
  
 // 
  
 Config 
  
 goes 
  
 here 
  
 }, 
 } 
 

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:

  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 
  
 } 
  
 } 
  
 } 
 } 
 

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 
 / 
 password 
  
 sign 
 - 
 in 
 . 
  
 { 
  
 hd 
 : 
  
 'acme.com' 
 , 
  
 // 
  
 using 
  
 regex 
 : 
  
 / 
 @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: 
  
 () 
  
 = 
>  
 { 
  
 // 
  
 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 
 ; 
  
 }); 
  
 } 
 } 
 

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 
    >  
    <! -- 
      
     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 
    > 
    
  2. Create a FirebaseUiHandler instance to render in the HTML container, and pass the config element you created to it.

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

      const 
      
     ciapInstance 
      
     = 
      
     new 
      
     ciap 
     . 
     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

Create a Mobile Website
View Site in Mobile | Classic
Share by: