Реализация чата делится на Backend и Frontend части:
Backend
API чата
Интеграция чата требует реализовать API интерфейс для обмена данными между чатом и подключемым сайтом
Это необходимо для синхронизации информации о пользователях. Например, чтобы в чате отображались актуальные имена и аватарки пользователей сайта.
Примером реализации всех необходимых для чата интерфейсов будет служить этот файл https://github.com/imbasynergy/ImbaChat-OctoberCMS/blob/master/controllers/apiChat.php
Авторизация
Все запросы от ImbaChat к интегрируемому сайту содержат параметры для авторизации, позволяющие проверить, что запрос действительно прислан от чата.
При настройке параметров виджета в личном кабинете есть параметры API login
и API password. Oни передаются при обращениях с сервера чата к серверу подключённого сайта в заголовке
Authorization.
Пример проверки авторизации на PHP:
$login = Settings::get('dev_login');
$password = Settings::get('dev_password');
if(!isset($_SERVER['PHP_AUTH_USER'])
|| ($_SERVER['PHP_AUTH_PW']!=$password)
|| strtolower($_SERVER['PHP_AUTH_USER'])!=$login)
{
header('WWW-Authenticate: Basic realm="Backend"');
header('HTTP/1.0 401 Unauthorized');
echo json_encode([
"code" => 401,
"version" => $this->getApiVersion()['version'],
"error" => 'Authenticate required!',
'debug' => ''
]);
die();
}
Как мы видим, в PHP параметры API login
и API password
из настроек виджета в личном кабинете на http://imbachat.com помещены в $_SERVER['PHP_AUTH_USER']
и $_SERVER['PHP_AUTH_PW']
Получение информации о пользователях
В личном кабинете в настройках виджета есть параметр Users info URL
для указания откуда чат должен брать информацию о пользователях.
На адрес Users info URL
чат будет отправлять запрос, передавая список идентификаторов пользователей по которым нужна информация.
В ответ ожидается json со структурой:
[
{
"user_id" : 6,
"name" : "Артём",
},
{
"user_id" : 6,
"name" : "Артём",
}
]
Поля user_id и name являются обязательными. Так же чат может принимать и обрабатывать дополнительные поля. Пример более подробного ответа с информацие о пользователях.
[
{
"user_id" : 6,
"avatar_url" : "http://comet-server.ru/doc/CometQL/Star.Comet-Chat/img/avatar0.png",
"name" : "Артём",
"profiles" : {
"11" : {
"user_id" : "P11-A",
"avatar_url" : "http://comet-server.ru/doc/CometQL/Star.Comet-Chat/img/avatar0.png",
"name" : "P11-Артём",
},
}
}
]
Обратите внимание, что в ответ ожидается именно массив с информацией об одном или более пользователях.
Пример реализации функции для отдачи информации о пользователях
<?php
// credentials for getting users data from server:
$login = "root"; // Лучше конечно вынести в конфигурационный файл. но для простоты примера захардкодили тут.
$password = "abc";
if(!isset($_SERVER['PHP_AUTH_USER']) || ($_SERVER['PHP_AUTH_PW']!=$password) || strtolower($_SERVER['PHP_AUTH_USER'])!=$login)
{
// AUTH FAIL
header('WWW-Authenticate: Basic realm="Backend"');
header('HTTP/1.0 401 Unauthorized');
echo json_encode([
"code" => 401,
"version" => $this->getApiVersion()['version'],
"error" => 'Authenticate required!',
'debug' => ''
]);
die();
}
// AUTH SUCCESS
// getting array of user ids:
$id_array = preg_replace("/[^0-9,]/", '', $_GET['user_ids']);
// establishing database connection:
$db_connection = mysqli_connect("localhost", "user", "pass","bd", 3306);
// set users table:
$users_table = "ktvs_users";
// set user ID column:
$users_param = "user_id";
// getting users from the database by their ids:
$sql = "SELECT * FROM $users_table WHERE $users_param IN ( $id_array )";
$users_query = mysqli_query($db_connection, $sql);
$num_rows = mysqli_num_rows($users_query);
$result = [];
if($num_rows>0)
{
while($rows = mysqli_fetch_assoc($users_query))
{
$user_id = $rows['user_id'];
$user_name = $rows['display_name'];
$login_date = $rows['last_login_date'];
$badge = $rows['custom10'];
if(!empty($rows['avatar']))
{
$avatar = "https://www.example.com/contents/avatars/".$rows['avatar'];
} else {
$avatar = false;
}
$link = "https://www.example.com/members/".$user_id."/";
$result[] = array(
'user_id' => $user_id,
'name' => $user_name,
'avatar_url' => $avatar,
'profile_url' => $link,
'lastlogin' => strtotime($login_date),
'badge' => $badge
);
}
}
// JSON object with users data:
echo json_encode($result);
Фронтенд
Авторизации пользователя в чате.
Для авторизации пользователей подключаемого сайта в чате необходимо правильно сгенерировать JWT токен и передать его как параметр user_key в объекте с другими параметрами инициализации чата.
Для генерации JWT токена, который чат примет как валидный, надо иметь секретный ключ (В личном кабинете подписан как Secret key
). Его можно получить в форме настроек вашего виджета в Личном кабинете.
Пример реализации функции для генерации токена
function getJWT($user_id, $secret_key, $time)
{
// Create token header as a JSON string
$header = json_encode(['typ' => 'JWT', 'alg' => 'HS256']);
$pass = $secret_key;
$data = array();
$data['exp'] = (int)date('U')+$time;
$data['user_id'] = (int)$user_id;
// Create token payload as a JSON string
$payload = json_encode($data);
// Encode Header to Base64Url String
$base64UrlHeader = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($header));
// Encode Payload to Base64Url String
$base64UrlPayload = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($payload));
// Create Signature Hash
$signature = hash_hmac('sha256', $base64UrlHeader . "." . $base64UrlPayload, $pass, true);
// Encode Signature to Base64Url String
$base64UrlSignature = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($signature));
// Create JWT
return trim($base64UrlHeader . "." . $base64UrlPayload . "." . $base64UrlSignature);
}
Первый аргумент - это параметр Secret Key, его можно поменять в настройках виджета в личном кабинете. Второй аргумент - это id пользователя в вашей базе данных, для которого генерируется JWT токен. Функция в ответ вернёт строку, которую вы используете в парамете user_key в настройке виджета.
Пример вызова функции для генерации токена:
$user_id = 1;
$secret_key = 'lPXBFPqNg3f661JcegBY0N0dPXqUBdHXqj2cHf04PZgLHxT6z55e20ozojvMRvB8';
echo getJWT($user_id, $secret_key, 3600);
То есть, встраивая в свой сайт виджет чата, вы сами реализуете систему аутентификации пользователей: при генерации страницы, на которой есть чат, определяется идентификатор пользователя, запросившего страницу, и персонально для него генерируете токен. В такой схеме проходит аутентификация кажого пользователя. Во фронтенд уже передается не Secret Key, а токен который сгенерирован с использованием этого ключа.
Чат, получая от пользователя токен, проверяет что он сгенерирован с использованием именно вашего ключа. И только после этого отдаёт переписку и список диалогов.
Frontend
Подключение виджета
-
Для начала нужно подключить javascript ImbaChat'а. Подключение выглядит так
<script src="http://api.imbachat.com/imbachat/v1/``DEV_ID``/widget"></script>
, где вместоDEV_ID
id виджета ( смотрите на странице виджета ). -
Далее мы вставляем скрипт загрузки чата:
function imbachatWidget(opt){ if(!window.ImbaChat){ return setTimeout(imbachatWidget, 50, opt) } window.ImbaChat.load(opt); } imbachatWidget({ user_id: "<?= $user_id ?>", token: "<?= getJWT($user_id, $secret_key, 3600) ?>" });
Создание диалога с пользователем. API виджета
Создание диалога между текущим пользователем и пользователем с id=2 (на пример для реализации кнопки "Написать сообщение" в профиле пользователя). Для создания диалога вызовите эту функцию и в качестве первого аргумента передайте id пользователя с которым вы хотите создать диалог.
window.imbaApi.openDialog(2)
Другие статьи: