Guides and Examples
Kindly Chat authentication
kindly supports authenticating your users with jwt tokens this process enhances your application and allows you to authenticate users for a more personalized and secure chat experience learn more about jwts at jwt io https //jwt io/introduction throughout this guide, we will cover a series of key tasks to set up this functionality adding a callback to the kindly chat initialization code to establish a secure connection with your application creating a private/public key pair, a fundamental part of secure data transfer developing an authentication endpoint that returns a json web token (jwt) in a specific format, which will be used to authenticate your users by the end of this setup, you will be able to view user details in the kindly insights and identify users in webhooks via the forwarded jwt sequencediagram participant u as user participant c as kindly chat client participant s as your server participant k as kindly u >>c start a chat c >>s call authentication endpoint s >>s generate jwt with private key s >>c return jwt c >>k send jwt k >>k verify jwt with public key opt webhook dialogue c >>k trigger a webhook dialogue k >>s webhook request with jwt s >>s verify jwt s >>k webhook response k >>c text reponse end add a callback to kindly chat the chat client embedded on your site will use a callback that will responsible for feeding the token to kindly you need to define a callback function on `window\ kindlysettings getauthtoken`, like the example below, which must return the jwt token the function is called with a single argument `chatid` which identifies the current chat typically, you would call your own backend to get the token, but you can also call a third party service or even generate the token directly in the browser example initialization code with callback using the browser fetch api \<script type="text/javascript"> window\ kindlyoptions = { getauthtoken async function (chatid) { return fetch("/your auth endpoint", { method "post", body json stringify({ chatid }), }) then((response) => response json()) then(({ token }) => token); }, }; \</script> \<script id="kindly chat" src="https //chat kindlycdn com/kindly chat js" data bot key="your bot key" async>\</script> create a private/public key pair to allow your own server to authenticate webhook requests without the kindly api interfering, we use a standard private/public key pair the private key is used by your server to encode and sign the jwt in your authentication endpoint add your public key to your bot under settings > kindly chat > authentication the public key is used by the api to verify that the jwt is valid run the following commands to generate a key pair on a linux or unix like environment openssl genrsa out private pem 2048 openssl rsa in private pem outform pem pubout out public pem on a windows environment ssh keygen t rsa b 2048 f private pem ssh keygen f private pem e m pem > public pem the contents of private pem should look something like \ begin rsa private key miieowibaakcaqeasufro2/65cn2vlsqjydedgfwnivezqowut0z7qhzcdhbq2iv +8l4ahkephz1lzs2/fejkrtmctprr/jcrvbjgf+shbw0hnsamovsvapy6k1w6qul \ end rsa private key and the contents of public pem should look like this \ begin public key miibijanbgkqhkig9w0baqefaaocaq8amiibcgkcaqeasufro2/65cn2vlsqjyde dgfwnivezqowut0z7qhzcdhbq2iv+8l4ahkephz1lzs2/fejkrtmctprr/jcrvbj \ end public key create an authentication endpoint the responsibility of authenticating your users is yours and is done by an http endpoint you implement in the most common case, the kindly chat callback sends a http post request to an authentication endpoint you implement if the kindly chat javascript request is sent from the same domain as the endpoint, cors headers can be omitted create an authentication endpoint that returns a jwt https //jwt io/ in the format specified below be aware that jwts are encoded and signed, not encrypted, meaning anyone who has the token can read the content set up an authentication endpoint on your backend that returns a json web token (jwt) signed using the rs256 algorithm and the private key created in the step above, and the payload must conform to the following required format you can implement the auth endpoint however you wish we recommend using a compatible jwt library from the list at https //jwt io/ https //jwt io/ token format claim required description iat yes integer timestamp (epoch time) when the token is generated exp yes integer timestamp (epoch time) when the token is going to expire maximum 15 minutes after iat (being generated) iss yes string representing the issuer of this token sub yes string representing your id for the logged in user chat yes a json object containing the listed keys example { id "abc123", webhook domains \["example com", " example org"] } chat id yes string value provided by kindly chat, representing the current chat chat webhook domains array of domains a domain whitelist that kindly is allowed to forward the token to name string value representing the full name of the user displayed in kindly chat and insights email string value representing the email of the user displayed in kindly chat and insights email verified boolean value indicating whether the email is verified only verified emails are stored phone number string value representing the phone number of the user displayed in kindly chat and insights phone number verified boolean value indicating whether the phone number is verified only verified phone numbers are stored picture an url, which is publicly accessible, pointing to a user avatar displayed in kindly chat and insights you may also include any other property you want to use in your webhooks you can read more on jwt in the standard here https //tools ietf org/html/rfc7519 python example using django rest framework import datetime import jwt from django conf import settings from django http response import httpresponsebadrequest, jsonresponse from django utils import timezone from rest framework decorators import api view, permission classes from rest framework permissions import isauthenticated @api view(\['post']) @permission classes((isauthenticated,)) def auth(request) chat id = request data get('chat id') if not chat id return httpresponsebadrequest() now = timezone now() iat = int(now\ timestamp()) expires = int((now + datetime timedelta(minutes=1)) timestamp()) # jwt is valid for 1 minute user = request user payload = { 'iat' iat, 'exp' expires, 'chat' {'id' chat id}, 'sub' str(user id), 'name' user get full name(), 'email' user email, 'email verified' true, 'picture' 'https //example com/avatar jpg', } token = jwt encode(payload, settings chat client auth private key, algorithm='rs256') decode('utf 8') return jsonresponse({'token' token}, status=200) node js example using micro web framework import fs from "fs"; import path from "path"; import micro, { json } from "micro"; import jwt from "jsonwebtoken"; const privkeypath = path join( dirname, "private pem"); const privkey = fs readfilesync(privkeypath); export default micro(async (req, res) => { const { chat id chatid } = await json(req); if (!chatid) { throw new error("missing post parameter chat id"); } const token = jwt sign( { sub "123abc", name "john doe", picture "https //example com/avatar jpg", email "john doe\@example com", email verified true, chat { id chatid, webhook domains \["example com", " example org"], }, }, privkey, { algorithm "rs256", expiresin "5m", } ); return { token }; }); identify users in webhooks once the authentication setup is done, a jwt token from your authentication endpoint is passed to the kindly api which can send the token to a webhook you specify (using advanced replies) when a webhook contains a token it can be used to identify a user and provide support for a wide range of integration use cases you'll find the jwt token in the standard authorization header, ie authorization bearer \<jwt> remember, you can use the debug console https //docs v2 kindly ai/getting started with webhooks#ly inspect response to inspect webhook request and responses, including their headers webhook domains to prevent leaking tokens to unwanted third parties, the webhook domains a jwt token can be forwared to must be encoded in the token thus the tokens will not automatically be sent from kindly to all webhooks in a bot this also implies that the domains must be known in advance see the section about token format for more info verify jwt token using your public key to be able to act on behalf of the user in a webhook request, you first need to verify the jwt token, using the public key you generated earlier after you have done that, you can extract information from it and be sure of its authenticity note that kindly also verifies the jwt using the public key you provide to us the public key can be found under settings > kindly chat > authentication for your bot