How to use Identity verification

What is Identity Verification


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.


What is Impersonation?

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.


What is logged-in?

If the Widget Configuration includes the email or unique_id, the client is considered a logged-in user.


What is a user impersonation attack?

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.




How does Identity Verification protect your company?

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.




Set up Identity Verification

User hash is created using a unique secret key, which is accessible in the Hello panel. 


Step 1: Get Secret Key

  1. Login to MSG91 account and click on hello. 
  2. Go to all inbox and select the setting of chat Inbox. 
  3. In Widget Settings, under configuration, you will find the secret key. 



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.


Step 2: Generate and send hashes for your users


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.


Step 3: Verify JWT

  1. Once after creating your JWT Token, verify it by clicking on "Verify JWT."
  2. Copy your dynamically created JWT and if it shows Signature Verified you are all set.



Step 4: Send JWT in Widget Configuration

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>
}



Regenerate Secret Key


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.




Hash Key Verification

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.


For Logged-Out Scenarios (When No Unique_ID or Email is Available):

No user JWT token is required, and the functionality will remain unchanged.


JWT Creation Information:

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.