JC-WebClient представляет из себя приложение на основе технологии локального Web-сервера, которое работает на стороне клиента. Приложение:
JC-WebClient поддерживает:
Архитектура JC-WebClient приведена на рисунке ниже:
Основные компоненты JC-WebClient:
JC-WebClient поддерживает работу со следующими средствами электронной подписи (далее – токенами) в форм-факторах USB-токен или смарт-карта:
Средство электронной подписи | В состав каких устройств входит |
---|---|
“Криптотокен 2 ЭП” Будем далее называть токен GOST 2 |
|
“Криптотокен ЭП” Будем далее называть токен GOST |
|
Токен PRO |
|
В качестве доверенного Trust Screen-устройства JC-WebClient поддерживает устройство Антифрод-терминал – собственный продукт компании «Аладдин Р.Д.».
Для возможности работы с JC-WebClient через JavaScript API необходимо последовательно выполнить следующие действия (полный пример первых 3-х пунктов представлен в разделе Начало работы):
Загрузите скрипт JCWebClient.js
с локального адреса: https://localhost:24738/JCWebClient.js.
На данном этапе необходимо учесть ситуацию, если на ПК пользователя отсутствует JC-WebClient,
поэтому для загрузки скрипта JCWebClient.js
рекомендуется следовать следующему алгоритму:
1.1. Средствами JavaScript попытайтесь асинхронно загрузить JCWebClient.js
.
1.2. Если скрипт загрузился успешно, то следует перейти к пункту 2, в противном случае - перейти к следующему шагу.
Для этого параллельно основному процессу выполните следующее:
Отобразите пользователю информационное сообщение о необходимости установить JC-WebClient. В этом же сообщении сообщите о том, что загрузка инсталлятора JC-WebClient на ПК пользователя начнётся автоматически, но если не началась в течение, например, 5 секунд, предложите нажать на специальную ссылку для скачивания инсталлятора с Web-сервера.
Выполните автоматическую загрузку инсталлятора JC-WebClient на ПК пользователя с Web-сервера вашего приложения.
Примечание
Если пользователь работает на платформе macOS, то после установки потребуется перезагрузка ПК (инсталлятор JC-WebClient уведомит об этом).
Примечание
Если пользователь использует браузер Mozilla Firefox, то после установки потребуется перезапустить все его открытые экземпляры.
1.4. Ожидайте N секунд.
1.5. Средствами JavaScript повторно попытайтесь асинхронно загрузить JCWebClient.js
в ожидании, что пользователь установил JC-WebClient.
1.6. Если скрипт загрузился успешно, то следует перейти к пункту 2, в противном случае - вернитесь к пункту 1.4.
Пример реализации алгоритма загрузки скрипта JCWebClient.js
// 1. Загрузка скрипта JCWebClient.js
getJCWebClient({
onLoad: function() {
// Скрипт JCWebClient.js загружен и модуль JCWebClient2 установлен
console.log('JC-WebClient установлен');
},
onError: function(error) {
// Скрипт JCWebClient.js не загружен
this.onError = undefined; // очищаем callback для того, чтобы код ниже выполнился только самый первый раз
// Отобразите пользователю информационное сообщение о необходимости установить JC-WebClient.
// В этом же сообщении сообщите о том, что загрузка инсталлятора JC-WebClient на ПК пользователя
// начнётся автоматически, но если не началась в течение, например, 5 секунд,
// предложите нажать на специальную ссылку для скачивания инсталлятора с Web-сервера.
console.log('Установите JC-WebClient !!!');
}
});
/** Функция цикличной загрузки модуля JCWebClient2.
Асинхронная функция.
@param params - объект с callback-функциями:
onLoad - функция срабатывает при успешной установке модуля JC-WebClient. Может быть вызвана только один раз;
onError - функция срабатывает неудачной установке модуля JC-WebClient. Может быть вызвана несколько раз.
*/
function getJCWebClient(params) {
// Проверка наличия модуля JCWebClient2 на Web-странице
if (typeof(JCWebClient2) !== 'undefined') {
// Модуль JCWebClient2 установлен
params.onLoad();
return;
}
// Получение скрипта JC-WebClient
getScript(
'https://localhost:24738/JCWebClient.js',
params.onLoad,
function(error) {
if(typeof(params.onError) === 'function') {
params.onError(error);
}
// Повторная попытка получения скрипта после 2-х секундного таймаута
setTimeout(function() {
getJCWebClient(params);
}, 2000);
}
);
}
/** Функция загрузки скрипта.
@param src - адрес расположения скрипта;
@param done - callback-функция, срабатывающая при успешной загрузки скрипта;
@param fail - callback-функция, срабатывающая при неудачной загрузки скрипта.
*/
function getScript(src, done, fail) {
var parent = document.getElementsByTagName('body')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = src;
if (script.readyState) { // IE
script.onreadystatechange = function () {
if (script.readyState === "loaded" || script.readyState === "complete") {
script.onreadystatechange = null;
// На некоторых браузерах мы попадаем сюда и в тех случаях когда скрипт не загружен,
// поэтому дополнительно проверяем валидность JCWebClient2
if (typeof (JCWebClient2) === 'undefined') {
onFail("JCWebClient is invalid");
}
else {
done();
}
}
else if (script.readyState !== "loading") {
onFail("JCWebClient hasn't been loaded");
}
}
}
else { // Others
script.onload = done;
script.onerror = function() {
onFail("JCWebClient hasn't been loaded");
};
}
parent.appendChild(script);
function onFail(errorMsg) {
parent.removeChild(script);
fail(errorMsg);
}
}
После успешной установки модуля JCWebClient2 инициализируйте его функцией initialize.
// 2. Инициализация JC-WebClient
JCWebClient2.initialize();
Проверьте версию JC-WebClient.
На данном этапе следует проверить, соответствует ли версия JC-WebClient пользователя той, которая поддерживается Вашим Web-приложением. Для этого рекомендуется следовать следующему алгоритму:
3.1. Асинхронно получите версию JC-WebClient командой getJCWebClientVersion.
3.2. Если версия поддерживается Вашим Web-приложением (т.е. Вы провели тестирование этой версии с Вашим Web-приложением), то следует перейти к пункту 4, в противном случае - перейти к следующему шагу.
3.3. Сообщите пользователю о том, что для корректной работы Web-приложения необходима другая версия JC-WebClient и далее можете:
3.4. Ожидайте N секунд.
3.5. Повторно асинхронно получите версию JC-WebClient командой getJCWebClientVersion в ожидании, что пользователь установил необходимую версию.
3.6. Если версия поддерживается Вашим Web-приложением, то перезагрузите текущую Web-страницу, в противном случае - вернитесь к пункту 3.4.
Пример реализации проверки версии JC-WebClient
// 3. Цикличная проверка версии JC-WebClient
checkJCWebClientVersion(function() {
// Версия JC-WebClient корректна
console.log('Версия JC-WebClient корректна. Продолжаем работу...');
});
/* Функция цикличной проверки версии JC-WebClient.
Асинхронная функция.
@param done - callback-функция, срабатывающая при успешной проверке версии JC-WebClient.
*/
function checkJCWebClientVersion(done) {
var failureCount = 0; // Счетчик некорректных версий
// Начать проверку версии JC-WebClient
checkVersion();
// Внутренняя функция проверки версии JC-WebClient
function checkVersion() {
// Получение версии JC-WebClient
JCWebClient2.getJCWebClientVersion({
async: true,
onResult: function(version, error) {
if(typeof(error) !== 'undefined') {
// Можно обработать ошибки в соответствии с бизнес-логикой
console.log('Ошибка получения версии JC-WebClient: ' + error);
}
// Проверка версии JC-WebClient
if(/* Условие некорректности version */) {
// Версия не подходит
++failureCount;
if(failureCount === 1) {
// Сообщите пользователю о том, что для корректной работы Web-приложения
// необходима версия JC-WebClient, отличная от текущей.
// Это сообщение отобразится только самый первый раз
console.log('Обновите JC-WebClient !!!');
}
// Повторная проверка версии JC-WebClient после 2-х секундного таймаута
setTimeout(function() {
checkVersion();
}, 2000);
return;
}
if(failureCount !== 0) {
// Перезагрузить страницу, т.к. ранее был подключен JC-WebClient неподходящей версии
window.location.reload();
return;
}
// Версия JC-WebClient корректна
done();
}
});
}
}
Рекомендуем подписаться на уведомления от JC-WebClient для отслеживания событий подключения/отключения токенов и изменения состояния аутентификации (см. Работа с событиями).
После описанных выше действий Web-страница готова к последующей работе с JC-WebClient.
При работе с USB-токенами и смарт-картами (устройствами) необходимо выбрать на устройстве криптографическое приложение (токен). На одном устройстве может быть несколько токенов. Различные токены обладают различной функциональностью: например, GOST и GOST 2 реализует российские криптоалгоритмы, а PRO – западные. Для работы с токенами в JC-WebClient API предусмотрены слоты.
Для получения массива слотов всех токенов (в том числе Антифрод-терминала без смарт-карты), подключенных к ПК, используйте команду getAllSlots:
var slots = JCWebClient2.getAllSlots();
Например, если к ПК подключено устройство JaCarta PRO/ГОСТ (на нём 2 поддерживаемых токена – PRO и GOST), то команда getAllSlots вернёт массив из двух объектов с разными идентификаторами слотов: один – для PRO, второй – для GOST.
Схема ниже иллюстрирует общий случай связи слотов с токенами и устройствами:
Из схемы видно, что при подключении нескольких устройств (USB-токен, смарт-карта в Антифрод-терминале) каждый токен устройства (а также Антифрод-терминал без смарт карты) будет закреплен за отдельным слотом, которые используются как идентификаторы в JC-WebClient API.
После получения массива слотов выберите токен, с которым вы хотите продолжать работать. Используйте команду getTokenInfo для получения информации о токене. Отсортировать массив токенов по их типу можно следующим образом:
var TokenPRO = [];
var TokenGOST = [];
var TokenGOST2 = [];
var AntifraudWithoutSmartCard = [];
for (i = 0; i < slots.length; i++) {
var slot = slots[i];
// Определяем антифрод-терминал без смарт-карты
if (typeof(slot.reader) !== 'undefined'
&& slot.reader.type === JCWebClient2.Vars.ReaderType.antifraud
&& slot.tokenExists === false) {
AntifraudWithoutSmartCard.push(slot);
continue;
}
// Получаем информацию о токене
try {
var tokenInfo = JCWebClient2.getTokenInfo({
args: {
tokenID: slot.id
}
});
switch(tokenInfo.type) {
case JCWebClient2.Vars.TokenType.pro: {
TokenPRO.push(slot);
break;
}
case JCWebClient2.Vars.TokenType.gost: {
TokenGOST.push(slot);
break;
}
case JCWebClient2.Vars.TokenType.gost2: {
TokenGOST2.push(slot);
break;
}
}
}
catch(error) {
console.error("Error: " + error);
}
}
Далее получите информацию о сертификатах, загруженных на токен. Для этого используйте следующие команды:
Полученную о сертификатах информацию необходимо отфильтровать и
После выбора сертификата, необходимо аутентифицироваться на токене с помощью PIN-кода пользователя. Без аутентификации токен будет работать в гостевом режиме с ограниченным функционалом: нельзя генерировать ключевые пары, создавать / изменять / удалять объекты на токене, создавать подпись и т.д. Для аутентификации необходимо запросить у пользователя PIN-код пользователя и использовать его при выполнения команды bindToken.
После успешной аутентификации токен переходит в режим пользователя, все пользовательские операции становятся доступными.
Узнать в каком режиме работает токен можно:
Для более подробного описания работы с командами см. раздел Выполнение команд.
С дополнительными примерами работы с токеном можно ознакомиться в разделе Примеры.
В JC-WebClient реализовано разделение контекста (сеансов работы с токеном) при работе из различных вкладок браузера. Это означает, что сеанс работы с токеном в режиме пользователя, установленный из одной вкладки, недоступен для других вкладок этого или другого браузера.
Контекст по умолчанию сохраняется при переходе с одной страницы на другую в рамках одной и той же вкладки браузера, а также при обновлении страницы (нажатие клавиши F5).
JC-WebClient предоставляет возможность явного указания на необходимость обнуления контекста при выходе за пределы данной Web-страницы.
Для этого установите на этой Web-странице значение параметра JCWebClient2.saveSession в false
:
JCWebClient2.saveSession = false;
Указанное значение параметра будет действовать только в пределах данной Web-страницы.
В JC-WebClient реализован таймаут в размере 1 минуты, по истечении которого контекст автоматически обнуляется, если приложение определило, что Web-страница перестала отвечать. При этом также удаляется и сеанс работы с токеном. Это произойдёт, например, в следующих случаях:
Примечание
Если в текущем сеансе работы с токеном был введён PIN-код, т.е. состояние аутентификации токена выше, чем JCWebClient2.Vars.AuthState.notBinded
,
то после обнуления контекста состояние станет равно JCWebClient2.Vars.AuthState.notBinded
, т.е. PIN-код потребуется вводить заново.
Более детальная информация по работе с JC-WebClient представлена в следующих разделах:
Функциональность JC-WebClient API