> ## Documentation Index
> Fetch the complete documentation index at: https://docs-dev-docs-event-stream-action-templates.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Learn how to keep users logged in to your application using silent authentication.

# Configure Silent Authentication

export const AuthCodeBlock = ({filename, icon, language, highlight, children}) => {
  const [displayText, setDisplayText] = useState(children);
  const [copyText, setCopyText] = useState(children);
  const wrapperRef = React.useRef(null);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      if (!window.autorun || !window.rootStore) {
        return;
      }
      unsubscribe = window.autorun(() => {
        let processedChildrenForDisplay = children;
        let processedChildrenForCopy = children;
        for (const [key, value] of window.rootStore.variableStore.values.entries()) {
          const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
          let displayValue = value;
          if (key === "{yourClientSecret}" && value !== "{yourClientSecret}") {
            displayValue = value.substring(0, 3) + "*****MASKED*****";
          }
          processedChildrenForDisplay = processedChildrenForDisplay.replaceAll(new RegExp(escapedKey, "g"), displayValue);
          processedChildrenForCopy = processedChildrenForCopy.replaceAll(new RegExp(escapedKey, "g"), value);
        }
        setDisplayText(processedChildrenForDisplay);
        setCopyText(processedChildrenForCopy);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  useEffect(() => {
    if (!wrapperRef.current) return;
    const originalWriteText = navigator.clipboard.writeText.bind(navigator.clipboard);
    let isOverriding = false;
    const handleClick = e => {
      const button = e.target.closest('[data-testid="copy-code-button"]');
      if (!button || !wrapperRef.current.contains(button)) return;
      isOverriding = true;
      navigator.clipboard.writeText = text => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
          return originalWriteText(copyText);
        }
        return originalWriteText(text);
      };
      setTimeout(() => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
        }
      }, 100);
    };
    const wrapper = wrapperRef.current;
    wrapper.addEventListener('click', handleClick, true);
    return () => {
      wrapper.removeEventListener('click', handleClick, true);
      if (navigator.clipboard.writeText !== originalWriteText) {
        navigator.clipboard.writeText = originalWriteText;
      }
    };
  }, [copyText]);
  return <div ref={wrapperRef}>
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight}>
        {displayText}
      </CodeBlock>
    </div>;
};

The [OpenID Connect protocol](/docs/authenticate/protocols/openid-connect-protocol) supports a `prompt=none` parameter on the authentication request that allows applications to indicate that the <Tooltip tip="Authorization Server: Centralized server that contributes to defining the boundaries of a user’s access. For example, your authorization server can control the data, tasks, and features available to a user." cta="View Glossary" href="/docs/glossary?term=authorization+server">authorization server</Tooltip> must not display any user interaction (such as authentication, consent, or <Tooltip tip="Authorization Server: Centralized server that contributes to defining the boundaries of a user’s access. For example, your authorization server can control the data, tasks, and features available to a user." cta="View Glossary" href="/docs/glossary?term=MFA">MFA</Tooltip>). Auth0 will either return the requested response back to the application, or return an error if the user is not already authenticated or if some type of consent or prompt is required before proceeding.

Use of the [Implicit Flow](/docs/get-started/authentication-and-authorization-flow/implicit-flow-with-form-post) in SPAs presents security challenges requiring explicit mitigation strategies. You can use the [Authorization Code Flow with PKCE](/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce) in conjunction with Silent Authentication to renew sessions in SPAs.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Recent advancements in user privacy controls in browsers adversely impact the user experience by preventing access to third-party cookies; therefore, browser-based flows must use [Refresh Token Rotation](/docs/secure/tokens/refresh-tokens/refresh-token-rotation), which provides a secure method for using refresh tokens in SPAs while providing end-users with seamless access to resources without the disruption in UX caused by browser privacy technology like ITP.
</Callout>

## Initiate Silent Authentication requests

To initiate a silent authentication request, add the `prompt=none` parameter when you redirect a user to the [`/authorize` endpoint of Auth0's authentication API](https://auth0.com/docs/api/authentication#authorize-application). (The individual parameters on the authentication request will vary depending on the specific needs of your app.)

For example:

export const codeExample = `GET https://{yourDomain}/authorize
    ?response_type=id_token token&
    client_id=...&
    redirect_uri=...&
    state=...&
    scope=openid...&
    nonce=...&
    audience=...&
    response_mode=...&
    prompt=none`;

<AuthCodeBlock children={codeExample} language="json" />

The `prompt=none` parameter causes Auth0 to immediately send a result to the specified `redirect_uri` (callback URL) using the specified `response_mode` with one of two possible responses: success or error.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Any applicable [rules](/docs/customize/rules) will be executed as part of the silent authentication process.
</Callout>

### Response modes

The `response_mode` parameter determines how Auth0 delivers the authorization response to your application. For silent authentication, you can use:

| Mode          | Delivery Method                    | Use Case                                               |
| ------------- | ---------------------------------- | ------------------------------------------------------ |
| `query`       | Query string (`?code=...`)         | Authorization Code flow with server-side handling      |
| `fragment`    | URL fragment (`#access_token=...`) | Implicit flow (legacy)                                 |
| `web_message` | `postMessage()` API                | **Recommended for SPAs** - no page navigation required |

When using `web_message`, Auth0 renders an HTML page inside a hidden iframe that uses the [HTML5 Web Messaging API](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) to communicate the result back to your application. This allows silent authentication without any visible page redirects or state loss.

<Note>
  To use `response_mode=web_message`, you must add your application's URL to the **Allowed Web Origins** field in your [application settings](https://manage.auth0.com/#/applications). For more details on all response modes, see [OAuth 2.0 Authorization Framework](/docs/authenticate/protocols/oauth#authorization-endpoint).
</Note>

### Successful authentication responses

If the user was already logged in to Auth0 and no other interactive prompts are required, Auth0 will respond exactly as if the user had authenticated manually through the login page. The format of the response depends on the `response_mode` used:

<Tabs>
  <Tab title="web_message">
    When using `response_mode=web_message` with Authorization Code Flow with PKCE (`response_type=code`), Auth0 returns an HTML page that posts the authorization code to your application:

    ```html theme={null}
    <script>
      window.parent.postMessage({
        type: 'authorization_response',
        response: {
          code: 'SplX...GT',
          state: 'your_state_value'
        }
      }, 'https://yourApp.com');
    </script>
    ```

    Your application (or SDK) listens for this message and exchanges the code for tokens. If the user has no valid session, Auth0 posts an error instead:

    ```html theme={null}
    <script>
      window.parent.postMessage({
        type: 'authorization_response',
        response: {
          error: 'login_required',
          error_description: 'Login required',
          state: 'your_state_value'
        }
      }, 'https://yourApp.com');
    </script>
    ```
  </Tab>

  <Tab title="fragment">
    When using `response_mode=fragment` (default for Implicit Flow with `response_type=id_token token`), Auth0 redirects with tokens in the URL fragment:

    ```text theme={null}
    GET https://yourApp.com/callback
        #id_token=eyJhbG...&
        access_token=eyJhbG...&
        state=your_state_value&
        expires_in=86400
    ```
  </Tab>

  <Tab title="query">
    When using `response_mode=query` (default for Authorization Code Flow with `response_type=code`), Auth0 redirects with the code in the query string:

    ```text theme={null}
    GET https://yourApp.com/callback
        ?code=SplX...GT&
        state=your_state_value
    ```
  </Tab>
</Tabs>

These responses are identical in format to a login performed directly without the `prompt=none` parameter. The only difference is that with `prompt=none`, the response is immediate without any user interaction.

### Error responses

If the user was not logged in via <Tooltip tip="Single Sign-On (SSO): Service that, after a user logs into one applicaton, automatically logs that user in to other applications." cta="View Glossary" href="/docs/glossary?term=Single+Sign-on">Single Sign-on</Tooltip> (SSO) or their SSO session had expired, Auth0 returns an error using the same `response_mode`. For redirect-based modes (`fragment` or `query`):

```text theme={null}
GET https://your_callback_url/
    #error=ERROR_CODE&
    error_description=ERROR_DESCRIPTION&
    state=...
```

For `web_message` mode, the error is posted via `postMessage()` as shown in the example above.

The possible values for `ERROR_CODE` are defined by the [OpenID Connect specification](https://openid.net/specs/openid-connect-core-1_0.html#AuthError):

| Response               | Description                                                                                                                                                                                                                                                                                                                                                                                                        |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `login_required`       | The user was not logged in at Auth0, so silent authentication is not possible. This error can occur based on the way the tenant-level **Log In Session Management** settings are configured; specifically, it can occur after the time period set in the **Require log in after** setting. See [Configure Session Lifetime Settings](/docs/manage-users/sessions/configure-session-lifetime-settings) for details. |
| `consent_required`     | The user was logged in at Auth0, but needs to give consent to authorize the application.                                                                                                                                                                                                                                                                                                                           |
| `interaction_required` | The user was logged in at Auth0 and has authorized the application, but needs to be redirected elsewhere before authentication can be completed; for example, when using a [redirect rule](/docs/customize/rules/redirect-users).                                                                                                                                                                                  |

If any of these errors are returned, the user must be redirected to the Auth0 login page without the `prompt=none` parameter to authenticate.

## Renew expired tokens

You can make a silent authentication request to get new tokens as long as the user still has a valid session at Auth0. The [`checkSession` method from auth0.js](/docs/libraries/auth0js) uses a silent token request in combination with `response_mode=web_message` for SPAs so that the request happens in a hidden iframe. With SPAs, Auth0.js handles the result processing (either the token or the error code) and passes the information through a callback function provided by the application. This results in no UX disruption (no page refresh or lost state).

### Access Token expiration

<Tooltip tip="Access Token: Authorization credential, in the form of an opaque string or JWT, used to access an API." cta="View Glossary" href="/docs/glossary?term=Access+Tokens">Access Tokens</Tooltip> are opaque to applications. This means that applications are unable to inspect the contents of Access Tokens to determine their expiration date.

There are two options to determine when an Access Token expires:

* Read the `expires_in` response parameter returned by Auth0.
* Ignore expiration dates altogether. Instead, renew the Access Token if your API rejects a request from the application (such as with a 401).

In the case of the [Implicit Flow](/docs/get-started/authentication-and-authorization-flow/implicit-flow-with-form-post), the `expires_in` parameter is returned by Auth0 as a hash parameter following a successful authentication. In the [Authorization Code Flow with PKCE](/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce), it is returned to the backend server when performing the authorization code exchange.

The `expires_in` parameter indicates how many seconds the Access Token will be valid for, and can be used to anticipate expiration of the Access Token.

### Error response

You may receive the `timeout` error response which indicates that timeout during executing `web_message` communication has occurred. This error is typically associated with fallback to cross-origin authentication. To resolve, make sure to add all of the URLs from which you want to perform silent authentication in the **Allowed Web Origins** field for your Application using the <Tooltip tip="Auth0 Dashboard: Auth0's main product to configure your services." cta="View Glossary" href="/docs/glossary?term=Auth0+Dashboard">Auth0 Dashboard</Tooltip>.

## Poll with checkSession()

In some multi-application scenarios, where Single Logout is desired (a user logging out of one application needs to be logged out of other applications), an application can be set up to periodically poll Auth0 using `checkSession()` to see if a session exists. If the session does not exist, you can then log the user out of the application. The same polling method can be used to implement silent authentication for a Single Sign-on (SSO) scenario.

The poll interval between checks to `checkSession()` should be at least 15 minutes between calls to avoid any issues in the future with rate limiting of this call.

## Silent authentication with Multi-factor Authentication

In some scenarios, you may want to avoid prompting the user for [Multi-factor Authentication (MFA)](/docs/secure/multi-factor-authentication) each time they log in from the same browser. To do this, set up a rule so that MFA occurs only once per session. This is useful when performing silent authentication (`prompt=none`) to renew short-lived Access Tokens in a SPA during the duration of a user's session without having to rely on setting `allowRememberBrowser` to `true`.

```js lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  const authMethods = event.authentication?.methods || []

  const completedMfa = !!authMethods.find((method) => method.name === 'mfa')

  if (!completedMfa) {
    api.multifactor.enable('any', { allowRememberBrowser: true })
  }
};
```

To learn more, see [Change Authentication Request Frequency](/docs/secure/multi-factor-authentication/customize-mfa).

## Learn more

* [Refresh Token Rotation](/docs/secure/tokens/refresh-tokens/refresh-token-rotation)
* [Configure Refresh Token Rotation](/docs/secure/tokens/refresh-tokens/configure-refresh-token-rotation)
