Vanilla HTML
Follow these steps to get started with Vanilla HTML.
-
Prepare a folder/directory. For this tutorial, we'll be using this directory structure:
project-root/ | +-- liveness/ | \-- index.html
The
liveness
folder/directory should contain the liveness engine and builders likebuilder.js
. -
Populate
index.html
. We will add more later.<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <!-- script and style definitions --> </head> <body> <!-- body --> </body> </html>
The
imports
section will be populated with script imports and style for better demo UI, and thebody
section will be populated with some html elements and a script to be loaded after the html elements are loaded. -
Replace
#!html <!-- script and style definitions -->
with script tag
below.<title>Document</title> <script src="./liveness/builder.js"></script> <style> #data-result { font-family: 'Courier New', Courier, monospace; white-space: pre-wrap; background-color: #0002; overflow: auto; } </style> </head>
The script tag above will import the WebSDK builder to be used in the tutorial application. It will then populate a
Builder
class in thewindow
global object. The style tag will then be used to style the data returned by the Liveness WebSDK. -
Replace
#!html <!-- body -->
with some HTML elements, as shown below.</head> <body> <button onclick="doLivenessVerification()"> Run Liveness Verification </button> <img id="image-result" src="" /> <div id="data-result"></div> <script> ((global) => { // Create Liveness WebSDK instance // Set up doLivenessVerification global function // Set up message receiver for Liveness WebSDK })(window); </script> </body>
- The
button
element is for starting the Liveness WebSDK process. - The
image
element with idimage-result
is for displaying the resulting image from the Liveness WebSDK. - The
div
element with iddata-result
is for displaying data result of the Liveness WebSDK. - The
script
element is used to prepare Liveness WebSDK and data handling from the SDK.
- The
-
Replace
#!js // Create Liveness WebSDK instance
with code below.((global) => { global.LivenessSDK = new LivenessBuilder() .setCredential({ clientId: 'YOUR_CLIENT_ID', secret: 'YOUR_SECRET', }) .setInstruction(['look_left', 'look_right'], { commands: ['open_mouth'], seedLimit: 1, }) .setProxyMiddleware({ PassiveLiveness: { url: 'http://localhost:8888/liveness/face', headers: { 'App-ID': '<replace-me-with-app-id>', 'API-Key': '<replace-me-with-api-key>', }, }, License: { url: 'http://localhost:8888/license/{license_id}/check', headers: { 'App-ID': '<replace-me-with-app-id>', 'API-Key': '<replace-me-with-api-key>', }, }, }) .setTimeout(60000) .setURL('./liveness') .setVirtualCameraLabel(['OBS', 'Virtual']) .build(); // Set up doLivenessVerification global function // Set up message receiver for Liveness WebSDK })(window);
Replace proxy middleware URLs with a URL that points to the correct endoints, and replace
<replace-me-with-app-id>
and<replace-me-with-api-key>
with the appropriate APP-ID and APIKey for the passive liveness (remove the headers if the api doesn't need credentials or the url is pointing towards an intermediate endpoint).Look Out!
To not accidentally leak of
AppID
andAPIKey
for passive liveness, always pass them to an intermediate endpoint (like a proxy middleware) and append theAppID
andAPIKey
header before reaching Verihubs' passive liveness service in production. Additional data can also be passed to this intermediate endpoint for end user identification.For more information about creating a Proxy Middleware, refer to Proxy Middleware.
For API documentation of the Builder, refer to
Builder
. -
Replace
#!js // Set up doLivenessVerification global function
with code below..build(); global.doLivenessVerification = function() { global.LivenessSDK.onStart(); }; // Set up message receiver for Liveness WebSDK })(window);
The code above creates a global function
doLivenessVerification
to be called by thebutton
element. This function then invokesonStart
function of the Liveness WebSDK instance upon being called by thebutton
element being clicked. -
Replace
#!js // Set up message receiver for Liveness WebSDK
with code below.}; global.addEventListener('message', function (message) { var data = message.data.data; var subject = message.data.subject; switch (subject) { case 'Verification.Verbose': console.log('[Verbose]', data); break; case 'Camera.NotAllowed': case 'Camera.NotFound': case 'Camera.PermissionDenied': case 'ScreenOrientation.NotAllowed': case 'Verification.Disrupted': case 'Verification.Timeout': console.log({ data, subject }); alert(subject); global.LivenessSDK.onDestroy(); break; case 'Verification.Success': setTimeout(function () { var imgElement = document.getElementById('image-result'); var dataElement = document.getElementById('data-result'); imgElement.src = 'data:image/png;base64,' + data.image.url; dataElement.innerText = JSON.stringify( data, undefined, 2 ); global.LivenessSDK.onDestroy(); }, 1500); break; default: console.log({ data, subject }); alert(subject); break; } }); })(window);
Info
Check System Messages for full system message references.
Combining all of the steps above, the full content file of index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="./liveness/builder.js"></script>
<style>
#data-result {
font-family: 'Courier New', Courier, monospace;
white-space: pre-wrap;
background-color: #0002;
overflow: auto;
}
</style>
</head>
<body>
<button onclick="doLivenessVerification()">
Run Liveness Verification
</button>
<img id="image-result" src="" />
<div id="data-result"></div>
<script>
((global) => {
global.LivenessSDK = new LivenessBuilder()
.setCredential({
clientId: 'YOUR_CLIENT_ID',
secret: 'YOUR_SECRET',
})
.setInstruction(['look_left', 'look_right'], {
commands: ['open_mouth'],
seedLimit: 1,
})
.setProxyMiddleware({
PassiveLiveness: {
url: 'http://localhost:8888/liveness/face',
headers: {
'App-ID': '<replace-me-with-app-id>',
'API-Key': '<replace-me-with-api-key>',
},
},
License: {
url: 'http://localhost:8888/license/{license_id}/check',
headers: {
'App-ID': '<replace-me-with-app-id>',
'API-Key': '<replace-me-with-api-key>',
},
},
})
.setTimeout(60000)
.setURL('./liveness')
.setVirtualCameraLabel(['OBS', 'Virtual'])
.build();
global.doLivenessVerification = function() {
global.LivenessSDK.onStart();
};
global.addEventListener('message', function (message) {
var data = message.data.data;
var subject = message.data.subject;
switch (subject) {
case 'Verification.Verbose':
console.log('[Verbose]', data);
break;
case 'Camera.NotAllowed':
case 'Camera.NotFound':
case 'Camera.PermissionDenied':
case 'ScreenOrientation.NotAllowed':
case 'Verification.Disrupted':
case 'Verification.Timeout':
console.log({ data, subject });
alert(subject);
global.LivenessSDK.onDestroy();
break;
case 'Verification.Success':
setTimeout(function () {
var imgElement =
document.getElementById('image-result');
var dataElement =
document.getElementById('data-result');
imgElement.src =
'data:image/png;base64,' + data.image.url;
dataElement.innerText = JSON.stringify(
data,
undefined,
2
);
global.LivenessSDK.onDestroy();
}, 1500);
break;
default:
console.log({ data, subject });
alert(subject);
break;
}
});
})(window);
</script>
</body>
</html>
To try the above implementation, you can host the folder/directory as the root of a HTTP server.
Updated 4 months ago