Identity Verification ensures private conversations and prevents impersonation of users. If you have a Chat Widget integration with logged-in users, using Identity Verification is strongly recommended.
Impersonation is a process where one user or entity temporarily assumes the identity and privileges of another, typically authorized for access to resources. It is often used for administrative or delegated functions while adhering to security and access controls.
If the Widget Configuration includes the email or unique_id, the client is considered a logged-in user.
Without Identity Verification, anyone can interact with your Widget and impersonate another user by providing a known identifier such as their email or unique_id. This can lead to an attacker posing as a legitimate user and gaining access to previous conversations, along with potentially sensitive data, which can be a significant risk to your team's security.
With Identity Verification, you generate a unique user hash for each of your users based on their email or unique_id and your company’s identity verification secret. Your integration will generate and send these hashes along with every Widget request allowing us to trust that the user request truly came from you.
User hash is created using a unique secret key, which is accessible in the Hello panel.
Keep the secret key confidential and do not expose it in public repositories.
Store the secret key in a secure environment.
The secret key is automatically generated when a Chat widget is created for a company in the Inbox.
Please note only owners and admins have access to the secret key. Only Integration Edit permission users can see the secret key and request for a new secret key.
Now you'll need to generate an HMAC on your server for each logged-in user and send it to Widget.
To generate user JWT tokens in different programming languages, please use the codes provided below as a reference.
Python
# requirement
$ pip install PyJWT
# code for generating jwt
import jwt
import time
# Header for jwt token
header_data = {
"alg": "HS256",
"typ": "JWT",
# Set verify_exp to True if you want to enable expiry of token else False
“verify_exp”: True
}
payload_data = {
"unique_id": "user_unique_id",
"mail": "user_email_address",
# For time in seconds pass seconds in seconds argument, for minutes pass minutes in minutes argument
"exp": datetime .datetime .now(tz=datetime.timezone.utc) + datetime.timedelta(seconds=60) }
# Your secret key
my_secret = ‘your_secret_key’
# Generating jwt token
token = jwt.encode(headers=header_data,
payload=payload_data,
key=my_secret,algorithm="HS256"
)
Node
# requirement
$ npm install jsonwebtoken
# code for generating jwt
// jwt token without expiry
var jwt = require('jsonwebtoken');
let my_secret = ‘your_secret_key’;
let payload = {
"unique_id": "user_unique_id",
“mail”: “user_email_address”,
}
// Set verify_exp to True if you want to enable expiry of token else False
var token = jwt.sign(payload, my_secret,{header: {“verify_exp”: false } })
// jwt token with expiry
var jwt = require('jsonwebtoken');
let my_secret = ‘your_secret_key’;
let payload = {
"unique_id": "user_unique_id",
“mail”: “user_email_address”,
“exp”:Math.floor(new Date().getTime() / 1000)
}
// Set verify_exp to True if you want to enable expiry of token else False
var token = jwt.sign(payload, my_secret,{algorithm:
"HS256"
header: {“verify_exp”: true } })
Java
# requirement
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<!-- or jjwt-gson if Gson is preferred -->
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<!-- Uncomment this next dependency if you are using JDK 10 or earlier
and you also want to use RSASSA-PSS (PS256, PS384, PS512) algorithms.
JDK 11 or later does not require it for those algorithms:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
<scope>runtime</scope>
</dependency>
-->
# code for generating jwt
Header header = Jwts.header();
header.setType("JWT");
header.put("verify_exp", true);
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
String jwtToken = Jwts.builder().setHeader((Map<String, Object>)header).setExpiration(now).signWith(SignatureAlgorithm.HS256,"your_secret_key".getBytes()).compact();
Note:
If mail and unique_id are passed then the user hash is calculated based on unique_id
If only mail is passed in JSON data without unique_id then mail is used to calculate the user hash.
If only unique_id is passed then unique id is used to calculate hash.
Pass generated JWT for logged-in users, E.g.
var helloConfig = {
widgetToken: "XXXXX",
user_jwt_token: "ENTER USER JWT TOKEN HERE",
unique_id: <unique_id>,
name: <name>,
number: <number>,
mail: <mail>
}
If required the secret key can be regenerated from the Hello end by clicking "Regenerate Secret Key."
The agent will be prompted to specify the expiration time for the old secret key, during which both the old and new secret key's JWT tokens will remain operational.
After this expiration, the old secret key will be deactivated, and any JWTs created with the old secret key will no longer be verified.
For Logged-In Users (When Email or Unique_ID is Provided in Widget Request):
The first step is to check the user's JWT token. If the user's JWT token is not provided in the request, a forbidden (403) request will be raised.
The user JWT token is authenticated at the Hello end using the same secret key employed by the widget's backend for JWT token generation. Therefore, it is imperative that widget integration aligns with the website backend. If the user's JWT token does not match, a forbidden response will be returned.
No user JWT token is required, and the functionality will remain unchanged.
The process of JWT creation is displayed on the panel, allowing clients to integrate the widget with the necessary JWT logic for different backend systems.
NOTE: This functionality is only available to the sites that have their backend manageable and can pass the jwt_token without exposing the secret key at UI.
For example, sites that are built on Shopify, WordPress, and other static sites.
It is crucial to implement Identity Verification in your Widget to prevent unauthorized access. Without Identity Verification, anyone can interact with your Widget and impersonate another user by providing a known identifier such as their email or unique_id. This can lead to an attacker posing as a legitimate user and gaining access to previous conversations, along with potentially sensitive data, which can be a significant risk to your team's security.