I eagerly look forward to the end credits of the Marvel movies because they tease you with tidbits of the next movie. In the last post, I made a passing reference to the Auth0 Action Hackathon, in which I was the runner-up. This project deserves its own blog post because its a great showcase for how you can swiftly pair an off-the-shelf industry-grade Auth0 Action from the Auth0 Marketplace, with a custom-built Auth0 Action that secures your unique login posture, and assemble them to make them work together. It also wowed the hackathon judges !!!
How Vaccinated are you? Integration with COWIN #
With in-person events gradually increasing in number, as event organizers, we have to follow local #COVID19 guidelines and policies. That is also one of avowed goals of Visage. In India. that means we have to verify an attendee's vaccination status with the country's online portal for it, COWIN.
In September'21, the Ministry of Health and Family Welfare had announced a COWIN API called as Know Your Customer/Client Vaccination status[KYC-VS]
It is a set of 3 protected API where you need to register before hand with your company details before access is given.
Given that the Govt do not want their systems to be unduly stressed, and it is geo-fenced, I am using the nifty Mock Server feature of Postman to simulate interactions with the COWIN API.
For our purposes, we will be using the Postman Collection of the COWIN KYC-VS API.
The collection has 3 requests:
Generate OTP
COWIN KYC-VS API requires you to generate an OTP before you can use the other APIs. The API is a POST request to the following endpoint:
https:/api/v3/vaccination/generateOTP
The request body is a JSON object with the following properties:
{
"mobile": "string",
"name": "string"
}The
mobile
field is the mobile number, and the name is the full name of the person whose vaccination status you want to check.In the response, you will receive a transaction ID, which you will need to use in the next request.
{
"txnId": "string"
}Validate OTP
Once you have the OTP, you can validate it with the following API:
https:/api/v3/vaccination/confirmOTPThe request body is a JSON object with the following properties:
{
"otp": "string",
"txnId": "string"
}The
otp
field is the OTP you received that has been SHA-256 encoded, and thetxnId
is the transaction ID you received in the previous request.If successful, you will receive a jwt-based bearer token, which you will need to use in the next request.
{
"token": "string"
}Get Vaccination Status
Once the authentication handshake is successfully validated, you can use the bearer token to get the vaccinationstatus of the person whose mobile number you used in the first request.
https:/api/v3β/vaccinationβ/statusThe response body is a JSON object with the following properties:
{
"vaccination_status": "0/1/2"
}The field
vaccination_status
can have only one of the following values:0
: Not Vaccinated1
: Partially Vaccinated2
: Fully Vaccinated
Auth0 is where the Action is #
Custom Action: KYC-VS #
Now that we have the Postman Collection of the COWIN KYC-VS API, we can use it in Auth0. We will be creating a custom Auth0 Action to encapsulate the entire interaction with the COWIN KYC-VS API.
Initially, we are going to make a call to the "generateOTP" method of the API, providing the mobile number and name of the person whose vaccination status we want to check.
To do this, we are going to add "axios" as a dependency to make those HTTP calls.
Axios is a promise-based HTTP client that works both in the browser and in a node.js environment. It basically provides a single API for dealing with XMLHttpRequests and node's http interface. Also, all the Auth0 Actions example have it as the HTTP client. So while in Rome.π
const axios = require('axios');
One of the great thing about the Auth0 Action editor is that it has a built-in Postman-like environment where you can test your code. This is a great developer productivity feature that shortens your dev feedback loop. Think about this..... the alternate would be logging in via a test app, and then checking the logs....been there, done that and it's so cumbersome.
Once you click on the Play icon on the top left [highlighted within the green box], then the Test Tab slides out with Event object pre-populated with dummy data, which you can edit.
Clicking the
Run
button just below theEvent
object will execute the action and after a few seconds, theTest Results
tab will pop out from the bottom to show the results of the execution. I have been quite liberal with the console.log statements so as to show the results of the execution.We can confirm from the Postman that the
txnId
is the same as the one that was sent.Next up, we need to create a SHA-256 of the OTP.
The eagle-eyed amongst you would have spotted that Auth0 Action has Node.js 16 as its runtime. That means, we can use the native crypto module to create the SHA-256 hash.
After importing the crypto module [highlighted in red below], we can use the createHash method to create a SHA-256 hash of the OTP[highlighted in yellow]. We are then invoking the
confirmOTP
of the COWIN API with a payload that consists of the hashed OTP along with the transaction ID received in the previous step. In response, we get the JWT token.The hashed OTP is the same as the one that on COWIN API portal
Homework: Put on your sleuthing hat, and see if you can decrypt the hashed OTP to reverse engineer the
COWIN_OTP
secret I used.Finally, we use the JWT token to get the vaccination status of the person whose mobile number we used in the first step.
The JWT token is sent as part of the Bearer token [highlighted in green]. Crucially, we store the vaccination status received as part of the payload, in the app metadata [highlighted in red]
We are storing the vaccination data in the app metadata and not in the user metadata because the latter can be updated by the user, and thats not what we want.
Market place Action: Yoonik Face Recognition #
The next step is to literally put a face
to the vaccination status. Yoonik is a modular SaaS platform that brings Developer-first Face Authentication
to any user on any device in minutes.
You need to create a Yoonik account, and post-that, an API key. You will need to copy the API key and the accompanying API secret, to configure the Yoonik Auth0 Action in the next step.
Next, we need to create a new Auth0 Action. We will be using the Yoonik Face Recognition action. Add the action to the Login Flow from the marketplace and then simply drag and drop it to the Flow editor. Follow the instruction in the
Installation
tab of the Yoonik Action in the Auth0 Marketplace to configure the action and you are in business. Its this simplicity of a mere drag & drop, and configuration to get an enterprise-grade Face Authentication that got me hooked. This is a great example of how you can use the Auth0 Action Marketplace to extend the functionality of your Auth0 tenant.
Codebase #
Time being of the essence in a hackathon, I had used the default Auth0 SPA Javascript quickstart project to showcase the whole solution. If you follow the instructions in the quickstart, you will have a working Auth0 tenant with a SPA application. You can either clone the GitHub repo or better still, download the project after logging in, and Auth0 will conveniently pre-fill up the auth_config.json
file with the details of your Auth0 tenant.
If every thing went well, you should be able to see the following screen when you run the project.
Next up, as mentioned in the Yoonik Auth0 Action installation instruction, you need to setup a custom application that implements the Yoonik Face Capture SDK. Yoonik have kindly provided a sample Python Flask application that does the same.
Assuming you have gone with the default port of 3031
, you need to add that URI to the callback and logout URL of your application in the Auth0 dashboard.
Once click on the blue login button, you will be presented with the Auth0 Universal Login Box
On a successful login, your browser will be redirected to the Yoonik Face Capture application.
On clicking the Take Selfie
button, your browser will ask for permission to access your webcam.
Once you grant the permission, you will be presented with a screen that will ask you to take a selfie.
Perusing the browser console, you can glean that the Yoonik Face Capture application is loading the model, and attempting to detect a face. Once it detects a face, it will send the image to the Yoonik API for processing. If the image matches successfully with the one in the Yoonik database, you will be redirected to the Auth0 callback URL. If the image does not match, you will be presented with an error message.
Yoonik Face Capture Application will present a successful message if the image matches with the one in the Yoonik database, and you will be presented with a link to proceed further.
You can verify in the Auth0 portal from the user's app metadata that he/she has been successfully logged in via Yoonik, and their vaccination status has been updated.
On the login page, the sample Auth0 SPA application will display the gravatar image of the the logged in user. If there is no picture associated with the user, it will display the initial of the user's name.
From a UX perspective, there is no indicator of the vaccination status of the user. And even if we wanted to display it, we can't because, as evident from the browser console, the Auth0 SPA Javascript SDK does not expose the app metadata to the client. Also, the app is configured in Auth0 dashboard for the ID token sent as a JWT payload to the client to be OIDC conformant
; COVID vaccination status, while looming large over our life from 2021, is not part of the OIDC spec. Thats what we see in the browser console.
We will enhance our custom Auth0 Action by adding a custom claim to the ID token [highlighted in red], and verify the test results[highlighted in yellow]
If we re-login into the app, after deploying the action, the ID token will now have the vaccination status as a custom claim.
On the index page we will add two Font Awesome syringes icon next to the user's profile image.
Then on the javascript side, we will get the vaccination status and toggle the visibility of the syringe icons based on the vaccination status.
Voila! We now have a working Auth0 SPA application that can display the vaccination status of the user.
What about when the user has taken only a single vaccination dose? Let's modify the vaccination status in the Postman.
Re-login into the app, and you will see that there is only one syringe icon next to the user's profile image.
Finally, what about when the user has not taken any vaccination dose? After modifying the vaccination status in Postman, re-logging into the app, and we see that there are no syringe icons next to the user's profile image.
Gotchas #
One thing that ate a lot of crucial time during the hackathon was a Javascript bug that never cropped up when testing in the Action Editor.
So while testing in the editor it was working fine, but post deploying and using in the app, it was failing. Presently this bug is not manifesting with the Node 16 runtime.
If you revert to a past version of an action and run the test in editor, it will still execute the previously deployed version of the action. Only if you make a change and save it, will it run the latest version of the action.`
πππ
Since you've made it this far, sharing this article on your favorite social media network would be highly appreciated π! For feedback, please ping us on Twitter.
Published