DirectWeb Integration

Please note that LoginID authentication currently supports the platform authenticators (device built-in) which allow the user to authenticate using their biometrics. We are currently working to finalize our support for the roaming authenticators (security keys).

DirectWeb Integration

This DirectWeb Developer’s Quickstart Guide serves as an integration guide for our trusted partners so that you will be able to evaluate, test, and launch LoginID’s authentication service using our DirectWeb API.

The DirectWeb API is made available to your web application via the LoginID JavaScript SDK. In contrast to the OpenID Connect flow, the DirectWeb API allows you to leverage LoginID’s authentication capabilities while allowing the user experience to remain completely within your domain.

When the user desires to register or login, your web application should call LoginID’s JavaScript SDK as described below in the document. This allows the SDK to take over the flow from the client-side, without forcing you to manage the nuances of security when interacting with LoginID’s backend.

Depending on the type of authentication requested (e.g. FIDO2, OTP, Password), you maybe able to specify callback functions to manage very specific aspects of the flow via the options field. However, this capability is not available for all authentication types as the flow may not be conducive to such customized experiences.

Our current version of DirectWeb SDK supports only FIDO2 Authentication type.

For example, if the authentication type is FIDO2, the native browser experience as defined by the browser vendor, will drive the experience regarding how the biometrics are requested. On the other hand, if the required authentication is OTP based, you may have an option to specify the UX widget that will receive the OTP from the user.

Step 1 - Obtain your client keys

In order for the LoginID JavaScript SDK to manage the DirectWeb functionality on your behalf, it needs to be configured with your credentials, which you can obtain from LoginID’s dashboard.

To obtain the API key you will need to perform the following steps:

Create a new admin account

  • Navigate to https://usw1.loginid.io/en/register and select the “Register a new account” option and follow the instructions to create a new account on LoginID’s dashboard.

  • Use the navigation bar to select “Integration” and choose Direct Web type.

Create Credentials

In the resulting form, you must enter the following information:

  • App Name

  • Website URL

Please note that unlike in the OpenID Connect flow, the Website URL is not a callback URL, but the top-level domain that is integrating the DirectWeb API functionality. LoginID’s backend will essentially whitelist this domain against your client profile as an allowable domain to issue cross-origin requests via the DirectWeb API.

Moreover, a callback URL is not needed as with the OpenID Connect integration, since the user experience never leaves your domain when using the DirectWeb API. Therefore, returning back to your domain via a callback URL is not required.

If the Website URL is not specified correctly, the DirectWeb API functionality will fail.

Once you create a new integration you will be provided with the following on our dashboard:

  • The API key is used to configure LoginID’s JavaScript SDK from your web application

  • Base URL which provides our SDK which LoginID environment the integration will be using

  • SDK Script is CDN hosted script you will be used to integrate with our backend

Once the SDK request is submitted (for example via a login or registration by the end user), you will receive an API key and a JWT verification public key. The JWT verification public key can be used to verify the JWT object that is returned by the DirectWeb API once the user registration/login is complete.

While you should generally store the API Key securely (i.e. don’t post it on the internet!), it is not strictly treated as confidential information since any motivated attacker can inspect your web application in their own browser and ascertain the API Key that is used to configure LoginID’s JavaScript SDK. However, this API Key is not very useful for such an attacker since the API key is tightly coupled to the Registered URL that you defined previously, such that it is not practical for the attacker to use the API key on their own web application hosted under a different domain.

Moreover, using the API Key on the attacker’s own customized browser to spoof the origin URL can be mitigated and can be further discussed as necessary.

For the first iteration of the DirectWeb API, the result of the authentication will be returned to the frontend web application directly, where the returned JWT may be verified using the JWT verification public key on your backend for additional assurance. Therefore, a shared secret to facilitate direct backend-to-backend communication (or asymmetric equivalent) is not necessary, but for additional security enhancements in the future, maybe provided with a subsequent version of the DirectWeb API.

Step 2 - Getting LoginID JavaScript SDK

The next step is to integrate the LoginID JavaScript SDK to the web application and this can be achieved by copying the SDK script on Step 1 into a .js file.

You can download the LoginID JavaScript SDK files from the following URLs:

After downloading the SDK file, save it to your vendor/project folder.

Step 3 - Configuring the SDK

Next, the SDK must be initialized with the base URL and API key that were obtained from LoginID’s dashboard in Step 1.

HTML + JS
JavaScript Framework
HTML + JS
<!-- Import directweb module from LoginID JS SDK -->
<script src="./src/vendor/loginid.directweb.min.js"></script>
<script>
/**
* Given a base URL and an API key, return a DirectWeb object that
* allows the registration and authentication operation.
*
* DirectWeb constructor takes the following parameters:
* baseURL:String the base URL where the credentials were created
* apiKey:String the API key created at LoginID dashboard
*/
const dw = new DirectWeb(
"https://directweb.usw1.loginid.io", "fLari955o86zbedHVT...lcRKoZMoIQ=="
);
// ...
</script>
JavaScript Framework
// Import directweb module from LoginID JS SDK
import DirectWeb from "/src/vendor/loginid.directweb.min";
/**
* Given a base URL and an API key, return a DirectWeb object that
* allows the registration and authentication operation.
*
* DirectWeb constructor takes the following parameters:
* baseURL:String the base URL where the credentials were created
* apiKey:String the API key created at LoginID dashboard
*/
const dw = new DirectWeb(
"https://directweb.usw1.loginid.io", "fLari955o86zbedHVT...lcRKoZMoIQ=="
);
// ...

Step 4 - Registration with an existing user credential

To check FIDO compatibility for your user, call the following method:

HTML + JS
JavaScript Framework
HTML + JS
<!-- Import browser module from LoginID JS SDK -->
<script src="./src/vendor/loginid.browser.min.js"></script>
<script>
/**
* Method to check for browser Fido2 support, returns true or false.
*/
const isFido2Supported = await LoginID.browser.default.isFido2Supported();
// ...
</script>
JavaScript Framework
// Import browser module from LoginID JS SDK
import Browser from "/src/vendor/loginid.browser.min";
/**
* Method to check for browser Fido2 support, returns true or false.
*/
const isFido2Supported = await Browser.isFido2Supported();
// ...

The code snippet for requesting registration of a new credential for the given username is shown below.

HTML + JS
JavaScript Framework
HTML + JS
<!-- Import directweb module from LoginID JS SDK -->
<script src="./src/vendor/loginid.directweb.min.js"></script>
<script>
// ... SDK configuration ...
/**
* Given a username, return a register object with username,
* namespace and JWT.
*
* Register method takes the following parameter:
* username:String the username provided by the user
*/
const result = await dw.register("john.doe");
</script>
JavaScript Framework
// Import directweb module from LoginID JS SDK
import DirectWeb from "/src/vendor/loginid.directweb.min";
// ... SDK configuration ...
/**
* Given a username, return a register object with username,
* namespace and JWT.
*
* Register method takes the following parameter:
* username:String the username provided by the user
*/
const result = await dw.register("john.doe");

The username is a mandatory field that must be passed into the register function.

The returned object from the function will have three elements: username, namespace, and JWT. If you want to know the registered username (which will match the input username if this field is populated), the username field in the returned object can be used along with the namespace field which is unique for your organization.

If backend assurance is required regarding the result, you can verify the JWT value with the JWT verification public key which can be obtained at the linked below:

curl https://jwt.usw1.loginid.io/certs?kid=<key id here>

where the kid is obtained from the JWT header:

{
"alg": "ES256",
"typ": "JWT",
"kid": "f82151ed-cdc4-447c-bb80-981bfbcc2497"
}

The JWT includes the username, credential type, nonce, timestamp, etc. signed by the LoginID private key that will correspond to the JWT verification public key.

Step 5 - Login with an existing user credential

The code snippet to requesting login with an existing credential is shown below.

HTML + JS
JavaScript Framework
HTML + JS
<!-- Import directweb module from LoginID JS SDK -->
<script src="./src/vendor/loginid.directweb.min.js"></script>
<script>
// ... SDK configuration ...
/**
* Given a username, return a login object with username,
* namespace and JWT.
*
* Login method takes the following parameter:
* username:String the username provided by the user
*/
const result = await dw.login("john.doe");
</script>
JavaScript Framework
// Import directweb module from LoginID JS SDK
import DirectWeb from "/src/vendor/loginid.directweb.min";
// ... SDK configuration ...
/**
* Given a username, return a login object with username,
* namespace and JWT.
*
* Login method takes the following parameter:
* username:String the username provided by the user
*/
const result = await dw.login("john.doe");

The discussion above in Step 4 regarding the parameters to and return an object from the register function is equally applicable to the login function here.

Getting help

We’re happy to assist, if you have any questions please don’t hesitate to contact dev@loginid.io.

Do you have any specific requests for the examples using other frameworks or programming languages? Contact us and let’s talk about bringing secure, private authentication to your application, we have engineers on standby to discuss.