Managing sessions with external identities

This article explains how to manage sessions with Identity-Aware Proxy (IAP) if you're using external identities for authentication.

Refreshing sessions

Identity Platform sessions are valid for one hour. When a session expires, your app needs to redirect to the authentication page. The authentication page contains the Identity Platform refresh token. As long as the user's credential is still valid, you can use it for reauthentication without showing any UI.

If the user recently changed their email or password, or some other action that revoked their token occurred, they'll need to complete the authentication flow again.

Handling non-AJAX requests

Non-AJAX requests are handled automatically using an application redirect, assuming the authentication page is configured correctly.

Handling AJAX requests

If you send an AJAX request with an expired token, the request will return a 401: Unauthorized status code. Implement one of the following solutions to handle this:

  • Modify your application code to handle HTTP 401 status codes.
  • Add an iframe to your application to point to the session refresher.
  • Instruct your users to manually load the session refresher in a separate tab.

If you're receiving a 302 status code instead of 401 in response to AJAX requests, add an X-Requested-With header with a value of XMLHttpRequest. This informs IAP that the request originates from JavaScript.

Programmatically handling HTTP 401

Programmatically handling HTTP 401 status codes is the recommended way to refresh an AJAX session. To do this:

  1. Update your application code to handle the error.

    if (response.status === 401) {
      statusElm.innerHTML = 'Login stale. <input type="button" value="Refresh" onclick="sessionRefreshClicked();"/>';

  2. Add a handler that opens a window to reauthenticate the user, then closes it when the process completes.

    var iapSessionRefreshWindow = null;
    function sessionRefreshClicked() {
      if (iapSessionRefreshWindow == null) {
        iapSessionRefreshWindow ="/_gcp_iap/do_session_refresh");
        window.setTimeout(checkSessionRefresh, 500);
      return false;
    function checkSessionRefresh() {
      if (iapSessionRefreshWindow != null && !iapSessionRefreshWindow.closed) {
        fetch('/favicon.ico').then(function(response) {
          if (response.status === 401) {
            window.setTimeout(checkSessionRefresh, 500);
          } else {
            iapSessionRefreshWindow = null;
      } else {
        iapSessionRefreshWindow = null;

Using an iframe

If you aren't able to handle HTTP 401 programmatically, the next best solution is to add an iframe to your application that points to the session refresher. For example:

<iframe src="" style="width:0;height:0;border:0; border:none;"></iframe>

Loading the session refresher

As a last resort, you can instruct your users to manually load the session refresher. Add guidance to your application or its documentation directing users to open the following URL in a separate tab:

Signing users out

To sign out a user from a IAP resource, use the query parameter ?gcp-iap-mode=GCIP_SIGNOUT. For example, in an App Engine app, the URL looks like this:

Users will be redirected back to the sign-in page after they're logged out.

To log out all currently signed in users, redirect them to your authentication URL with your API key and mode=signout appended as parameters. For example:

Users will remain on the page after sign-out completes. Consider implementing the completeSignOut() callback on the AuthenticationHandler object to provide feedback to the user that they've signed out successfully.

Switching between tenants

In some cases, a user might want to authenticate with several tenants for the same IAP resource. For example, they might belong to multiple tenants that grant different levels of access, and want to change to a tenant with fewer or greater privileges.

To force the tenant selection process to restart, use ?gcp-iap-mode=CLEAR_LOGIN_COOKIE. For example, in a App Engine app, the URL might look like this:

What's next