Vue
Follow these steps to get started with Vue.
-
Set up the workspace by running the following command:
npm create vue@latest livenesstestA folder/directory named
livenesstestshould appear and the folder/ directory structure should look like this:livenesstest/ | +-- node_modules/ | +-- public/ | | | \-- vite.svg | +-- src/ | | | +-- assets\ | | | +-- components\ | | | +-- App.vue | | | +-- main.js | | | \-- style.css | +-- .gitignore | +-- index.html | +-- vite.config.js | +-- package-lock.json | +-- package.json | \-- README.md -
Put the
livenessfolder/directory that contains the liveness engine and builders likebuilder.js, into thepublicfolder/directory. -
Add the liveness package to
package.jsonby running this command in thelivenesstestVue project.npm i file:public/livenessThis will add
@verihubs/livenessdependency inpackage.json. -
Create new file with name
useLiveness.tsinsidesrcfolder.touch src/useLiveness.ts -
Add the following code to the
useLiveness.tsfile insidesrcfolder.import { onBeforeUnmount, onMounted, ref } from "vue"; import Builder from "@verihubs/liveness"; export function useLivenessSDK() { const image = ref(""); const result = ref(""); const error = ref<string | null>(null); let sdk: ReturnType<Builder["build"]> | null = null; const start = () => { sdk?.start(); }; const destroy = () => { sdk?.destroy(); }; const handleMessage = ({ data: { data, subject }, }: { // eslint-disable-next-line @typescript-eslint/no-explicit-any data: { data: any; subject: string }; }) => { 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 }); error.value = subject; alert(subject); destroy(); break; case "Verification.Success": { window.setTimeout(() => { image.value = `data:image/png;base64,${data.image.url}`; result.value = JSON.stringify(data, undefined, 2); destroy(); }, 1500); break; } default: console.log({ data, subject }); error.value = subject; break; } }; onMounted(() => { sdk = new Builder() .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(); window.addEventListener("message", handleMessage); }); onBeforeUnmount(() => { window.removeEventListener("message", handleMessage); sdk?.destroy(); sdk = null; }); return { image, result, error, start, destroy, }; }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
AppIDandAPIKeyfor passive liveness, always pass them to an intermediate endpoint (like a proxy middleware) and append theAppIDandAPIKeyheader 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.InfoCheck System Messages for full system message references.
-
Replace
App.vuewith code below:<script setup lang="ts"> import { useLivenessSDK } from './useLiveness'; const { image, result, error, start } = useLivenessSDK(); </script> <template> <main> <button type="button" @click="start"> Run Liveness Verification </button> <p v-if="error"> {{ error }} </p> <img v-if="image" :src="image" alt="Liveness result" /> <pre v-if="result">{{ result }}</pre> </main> </template> <style scoped> pre { font-family: 'Courier New', Courier, monospace; white-space: pre-wrap; background-color: #0002; overflow: auto; } </style> -
Add the dependency to
optimizeDeps.includeandbuild.commonjsOptions.includein Vite.config.js with code below:export default defineConfig({ plugins: [vue()], optimizeDeps: { include: ["@verihubs/liveness"], }, build: { commonjsOptions: { include: [/liveness/, /node_modules/], }, }, });
To try the above implementation you can run the following command from the liveness project:
npm run dev