DEV Community

Cover image for Use Userfront live mode token for local development
Sundarapandiyan
Sundarapandiyan

Posted on

Use Userfront live mode token for local development

Userfront is a secure, full-featured platform for authentication and access control. It is simple for developers to incorporate into the application. Userfront React Example. When we develop it locally (localhost), it will always be in test mode. With the test mode accessToken developers are unable to test the live and sso.

Is there any way to use the live mode token

The accessToken from the live mode app will typically be copied by the developer and hardcoded in local for use. I'm utilising a way that auth0 uses in the getTokenSilently() method to automate this.

1. Create and deploy a Universal login page

To make a login page live, we must first create it and deploy it to a server.

// https://yourdomain.com #1

<html>
<head>
    <script id="Userfront-script">
        // Your Userfront script
    </script>
</head>
<body>
    <script>
        loginPageFunction = function () {
            const params = new URLSearchParams(window.location.search);
            const redirectUrl = params.get('redirectUrl')
            if (redirectUrl) {
                localStorage.setItem('redirectUrl', redirectUrl);
            }
            const token = Userfront.tokens.accessToken;
            if (token) {
                const storageRedirectUrl = localStorage.getItem('redirectUrl');
                if (storageRedirectUrl) {
                    localStorage.removeItem('redirectUrl');
                    location.href = storageRedirectUrl;
                } else {
                    var elemDiv = document.createElement('div');
                    elemDiv.id = "Your Userfront logout token";
                    document.body.appendChild(elemDiv);
                }
            } else {
                var elemDiv = document.createElement('div');
                elemDiv.id = "Your Userfront signin token";
                document.body.appendChild(elemDiv);
            }
        }
        document.onreadystatechange = function () {
            if (document.readyState == "complete") {
                loginPageFunction();
            }
        }
    </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

then add a functionality to return accessToken to your localhost

// https://yourdomain.com #final

<html>

<head>
    <script id="Userfront-script">
        // Your Userfront script
    </script>
</head>

<body>
    <script>
        loginPageFunction = function () {
            const params = new URLSearchParams(window.location.search);
            const redirectUrl = params.get('redirectUrl')
            if (redirectUrl) {
                localStorage.setItem('redirectUrl', redirectUrl);
            }
            const token = Userfront.tokens.accessToken;
            if (token) {
                const storageRedirectUrl = localStorage.getItem('redirectUrl');
                if (storageRedirectUrl) {
                    localStorage.removeItem('redirectUrl');
                    location.href = storageRedirectUrl;
                } else {
                    var elemDiv = document.createElement('div');
                    elemDiv.id = "Your Userfront logout token";
                    document.body.appendChild(elemDiv);
                }
            } else {
                var elemDiv = document.createElement('div');
                elemDiv.id = "Your Userfront signin token";
                document.body.appendChild(elemDiv);
            }
        }
        middlewareFunction = function () {
            const targetOrigin = 'http://localhost:3100' or your localhost address;
            const token = Userfront.tokens.accessToken;
            if (token && window.location.ancestorOrigins[0] == targetOrigin) {
                let message = {
                    response_type: "success",
                    token: token,
                    type: 'authorization_response',
                };
                window.parent.postMessage(message, targetOrigin);
            } else {
                let message = {
                    response_type: "error",
                    type: 'authorization_response',
                };
                window.parent.postMessage(message, targetOrigin);
            }
        }
        document.onreadystatechange = function () {
            if (document.readyState == "complete") {
                if (window.location == window.parent.location) {
                    loginPageFunction();
                } else {
                    middlewareFunction();
                }

            }
        }
    </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

2. get accessToken from live domain

To access the token, we now need to add a function to our code. In react, I added a service. yet angular and vue also support the same service. Userfront operates normally in live mode; however, it uses an iframe in local mode to obtain an accessToken.


// userFrontService.js

import Userfront from '@userfront/react';
const CLEANUP_IFRAME_TIMEOUT_IN_SECONDS = 2;
const DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS = 60;
const EVENT_ORIGIN = 'https://yourdomain.com';
const REQUEST_ORIGIN = 'localhost:3100';

class userFrontService {
  getToken = () => {
    if (window.location.host !== REQUEST_ORIGIN) {
      return new Promise((resolve, reject) => {
        const accessToken = Userfront.tokens.accessToken;
        if (accessToken) {
          resolve(accessToken);
        } else {
          reject(accessToken);
        }
      });
    }
    return new Promise((resolve, reject) => {
      var iframe = window.document.createElement('iframe');
      iframe.setAttribute('width', '0');
      iframe.setAttribute('height', '0');
      iframe.style.display = 'none';
      var iframeEventHandler: any;
      const timeoutInSeconds = DEFAULT_AUTHORIZE_TIMEOUT_IN_SECONDS;

      var removeIframe = function() {
        if (window.document.body.contains(iframe)) {
          window.document.body.removeChild(iframe);
          window.removeEventListener('message', iframeEventHandler, false);
        }
      };
      var timeoutSetTimeoutId = setTimeout(function() {
        reject('error');
        removeIframe();
      }, timeoutInSeconds * 1e3);
      iframeEventHandler = function(e) {
        if (e.origin != EVENT_ORIGIN) return;
        if (!e.data || e.data.type !== 'authorization_response') return;
        var eventSource = e.source;
        if (eventSource) {
          eventSource.close();
        }
        e.data.response_type == 'error' ? reject(e.data) : resolve(e.data.token);
        clearTimeout(timeoutSetTimeoutId);
        window.removeEventListener('message', iframeEventHandler, false);
        setTimeout(removeIframe, CLEANUP_IFRAME_TIMEOUT_IN_SECONDS * 1e3);
      };
      window.addEventListener('message', iframeEventHandler, false);
      window.document.body.appendChild(iframe);
      iframe.setAttribute('src', EVENT_ORIGIN);
    });
  };
  login = () => (location.href = `${EVENT_ORIGIN}?redirectUrl=${location.origin}`);
  isDevEnvironment = window.location.host === REQUEST_ORIGIN;
}
export default new userFrontService();

Enter fullscreen mode Exit fullscreen mode

To obtain the accessToken by default, we shall utilise Userfront.tokens.accessToken. Here, we'll refer to the service as the following

instead of
const token = Userfront.tokens.accessToken;

const token = await userFrontService.getToken();

3. Change your login accordingly


  const LoginForm = Userfront.build({
    toolId: 'Your login token ',
  });

  return (
        {userFrontService.isDevEnvironment ? (
          <>
            <Button onClick={() => userFrontService.login()}>Login</Button>
          </>
        ) : (
          <LoginForm />
        )}
      </div>
  );
Enter fullscreen mode Exit fullscreen mode

Adding https://yourdomain.com to a private network will increase security by limiting access to only developers working for your organization.

Thank you for reading, and let's connect!

Top comments (0)