Authorized Client Identification v2.0
N.B.
Below, this article describes the procedure for computing a hash of visitor fields. We strongly recommend that you use the HMAC-SHA256
algorithm
To transfer information about a visitor authorized on the site and further display it in the interface of the agent Rox.Chat you need to add the following javascript code to the pages of the site:
roxchat_visitor = {
fields: {
field: value,
field: value,
...
},
expires: timestamp,
hash: "crc"
};
Example (HMAC-SHA256
algorithm):
roxchat_visitor = {
fields: {
id: "12345",
display_name: "John",
phone: "+10432234376",
email: "abc@rox.chat"
},
expires: 1481195621,
hash: "07ef16b821f9552a8b3118416ed9ed6278d3a8ff93751d157c88edc1895cd86f"
};
Example (SHA256
algorithm):
roxchat_visitor = {
fields: {
id: "12345",
display_name: "John",
phone: "+10432234376",
email: "abc@rox.chat"
},
expires: 1481195621,
hash: "f859287203804f8f25123b3ea651338ac73cef970bec1066d061d75786c0dcb7"
};
N.B.
These examples and these checksums are calculated using the random key e64e356464255555f3ecd64ae7dbb600dca8
.
The checksum for your account is calculated based on the private key, which can be found in Settings -> Private Keys. The string representation of the private key is used, i.e. key=str(private_key)
.
N.B.
The private key should not be available to clients, the signature should be generated only on your server. Otherwise, the security of your clients will be compromised.
A list of supported fields in fields
:
-
id
is visitor ID (mandatory, unique) -
display_name
is visitor's name -
phone
is visitor's phone number -
email
is visitor's email address -
profile_url
is link to visitor's profile -
avatar_url
is link to visitor's avatar graphic file -
login
is login of visitor on the site -
comment
is visitor's comment -
info
is additional information -
high_priority
is visitor's priority
All field values must be strings.
Other fields (with their own names) can also be passed, they will be displayed in the first message of the chat and transmitted via API, but will be absent in the Workspace in the visitor data panel on the right side of the chat.
The id
field is mandatory (it is used to identify the user in the system). The field must contain a unique value, otherwise users with the same id
will have access to each other's messages. The rest of the fields are optional. In case the id
of a visitor changes, the system considers him as a new visitor or as an existing visitor in case his new id
is not unique.
The high_priority
field reflects the priority of the chat started by this visitor. If the chat was started from priority page, then the value of the high_priority
field is 1
. In other case, the field can have any other value. Priority can also be set manually by the client, if it is required that chats from certain visitors are processed first. For example, this approach can be used in a mobile application based on Rox.Chat Mobile SDK.
The expires
field should contain a timestamp (a number) indicating the point in time (in seconds) until which the submitted data is valid. The field is optional.
When using this parameter, it is necessary to ensure the validity of the provided data throughout the entire time of user interaction with the system: either the expires
value should be chosen with a large margin, or the data object should be periodically updated as the time specified in expires approaches. Filling this field serves as an additional protection system: in case of data theft, an attacker will not be able to authorize after the specified expires. That is, the visitor will not be able to perform actions, but the agent will still be able to respond to him and push notifications will continue to be sent to the push token specified when creating the session.
If it is necessary to leave the authorized zone before the time specified in expires
, it is necessary to pass the value null
in the roxchat_visitor
parameter.
The hash
field must contain a checksum.
Checksum Calculation
To calculate the checksum you need to:
-
Sort the json keys of fields (not values) from
fields
according to the alphabetical order of field names. -
Aggregate the field values into a single string.
-
If you are using
expires
- add the field value to the end. -
From the resulting string, calculate the checksum using the
HMAC-SHA256
algorithm with the account's private key.The choice of algorithm is determined by the
provided_visitor_hash_algorithm
system parameter. It is recommended to use exactly theHMAC-SHA256
algorithm.SHA-256
andMD5
are also available for selection, and the private key, if there is more than one, can be used.
The encoding when calculating hash
must be utf-8
.
To compute a hash using the HMAC-SHA256
algorithm, the calculation string should look like this:
hash = hmac.new(key=str(private_key), msg=msg, digestmod=hashlib.sha256).hexdigest()
where:
msg = 'Johnabc@rox.chat12345+104322343761481195621'
private_key = 'e64e35642555f3ecd64ae7dbb600dca8'
Or else:
hmac_sha256(display_name + email + id + phone + expires, "private key")
That is:
hmac_sha256("Johnabc@rox.chat12345+104322343761481195621", "private key")
Sample code for hash calculation using the HMAC-SHA256
algorithm (Java):
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;
private String buildUserHash(final String userHashSrc, final String secretKey) {
final Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
final byte[] secretKeyBytes = secretKey.getBytes("US-ASCII");
final SecretKeySpec secretKeySpec = new SecretKeySpec(secretKeyBytes, "HmacSHA256");
sha256_HMAC.init(secretKeySpec);
return Hex.encodeHexString(sha256_HMAC.doFinal(userHashSrc.getBytes("UTF-8")));
}
Sample code for hash calculation using HMAC-SHA256
algorithm (language: Python version 2):
# -*- coding: utf-8 -*-
import hashlib
import hmac
private_key='e64e35642555f3ecd64ae7dbb600dca8'
encoding = 'utf-8'
fields = {'phone': u'+10432234376', 'display_name': u'John', 'id': u'12345', 'email': u'abc@rox.chat'}
expires = 1481195621
msg_parts = []
for key in sorted(fields.keys()):
value = fields[key]
msg_parts.append(value.encode(encoding))
msg_parts.append(str(expires))
msg = ''.join(msg_parts)
hash_hmac = hmac.new(key=str(private_key), msg=msg, digestmod=hashlib.sha256).hexdigest()
Sample code for hash calculation using SHA256
algorithm (language: Python version 2):
# -*- coding: utf-8 -*-
import hashlib
import hmac
private_key='e64e35642555f3ecd64ae7dbb600dca8'
encoding = 'utf-8'
fields = {'phone': u'+10432234376', 'display_name': u'John', 'id': u'12345', 'email': u'abc@rox.chat'}
expires = 1481195621
msg_parts = []
for key in sorted(fields.keys()):
value = fields[key]
msg_parts.append(value.encode(encoding))
msg_parts.append(str(expires))
msg = ''.join(msg_parts)
hash_obj = hashlib.sha256()
hash_obj.update(msg)
hash_obj.update(private_key)
hash_sha = hash_obj.hexdigest().lower()
To check the checksum (hash), you can also use our online Visitor Fields Calculator by going to this page.
Prioritizing Visitor Fields
Information (fields) identifying the visitor may be transmitted in one or more of the following data sets:
-
fields
- recognized by the Rox.Chat service itself -
provided_fields
- transmitted by the frontend (in case of visitor authorization) -
opFields
- entered by the agent during the chat
There may be situations where the same fields are transmitted from different sources and do not match. In order to keep the set of fields about the visitor unified and without inconsistencies, it is possible to define a priority on which Rox.Chat will be oriented. The priority is set in the visitor_fields_priority_order
parameter of the account config settings: the highest-priority array of fields is specified first, followed by lower-priority fields in descending order. The default value of the parameter is ["providedFields", "fields", "opFields"]
, which means that if different values of the same field (e.g. visitor's phone number) are passed in several sets, the value from providedFields
will be included in a single set of fields about the visitor, and the other values will be ignored.
It is the final set of fields, obtained on the basis of the specified priorities, that will be displayed in the Workspace, transmitted via API or bot, and generally used in the system. It is important to keep in mind that not all data about the visitor are displayed in the Workspace during the chat, but the data that are not displayed are stored in the system and, if necessary, are transmitted to the necessary place in full.
Identification by Token
This method of identification is mutually exclusive with the one described above. To implement it, it is necessary to use the provide_visitor_fields
method from Rox.Chat Realtime API. Also, the functionality of the method is not available when the visitor chat widget is located inside an iframe.
Visitor Identification in Mobile Applications
If you are using the Rox.Chat Mobile SDK for iOS or Android, you can pass a data object in JSON format to the SDK to identify customers. Read more in the documentation:
Android Mobile SDK documentation
Identification When Using a Link to client.php
To correctly display the title and link of the page from which you opened the chat link, you can pass the start-page
parameter as a JSON value with title
and url
fields in the agent interface via GET, for example:
{
"title": "Main page",
"url": "https://example.com"
}
Possible Authentication Errors
Error | Description |
---|---|
provided-visitor-expired |
The validity of the data provided in roxchat_visitor has expired |
wrong-provided-visitor-expires-value |
Invalid value of the expires field. The error is caused when the value does not match the Int data type or when the field value is too large. |
wrong-provided-visitor-field-value |
Invalid value of one of the visitor's fields. The error is caused when the value does not match the String data type |
wrong-provided-visitor-hash-value |
Invalid visitor field checksum value, including an empty or missing field. |
provided-auth-token-not-found |
An error may occur during authorization by token. The provided token is not found in the system. More information about authorization by token can be found in this article. |