Аутентификация

MedMe EHR Server не имеет собственного сервера авторизации. Вместо этого используется обмен данными с существующим сторонним сервером авторизации по закрытому для конечного пользователя каналу.

Описание механизма обмена

На первом шаге вам необходимо авторизоваться на сервере авторизации — получить пару user, token. Поскольку авторизация выполняется через отправку OTP на номер телефона это подтверждает наличие владения телефона с указанным номером у пользователя.

Если пользователь аутентифицирован на стороне EHR сервера и у вас есть авторизация, которую вам дал авторизационный сервер — это значит, что вы авторизованы и на стороне EHR сервера - там сохранена пара user, token. Отправив запрос patient.get_patient на EHR сервер вы получите корректный ответ — данные о пациенте, а так же подпись пользователя user_sign.

Если пользователь не аунтефицирован на стороне EHR сервера вы получите соответствующее сообщение об ошибке. Для ее обработки вам нужно показать форму ввода данных, по которым можно идентифицировать пользователя. ВНИМАНИЕ! Эти данные могут быть приватными, поэтому отправлять их на сервер авторизации или через сервер авторизации нельзя. Вместо это вам необходимо отправить запрос на получение токена обмена (exchange_token) у авторизационного сервера. Это короткоживущий токен — время жизни 10 минут, который "знает" приложение и EHR сервер (сервер авторизации должен отослать его обоим; EHR сервер должен его запромнить). За время его жизни вам нужно выполнить второй запрос на аутентификацию и последующую авторизацию пользователя к серверу EHR. Если вы получите успешный ответ - поздравляю, вы аутентифицировали пользователя на стороне сервера EHR и можете работать с его данными. Если нет, то вам нужно обработать соответствующие сообщения об ошибке.

В случае, когда аутентификация пользователя на EHR сервере выполнена, сервер аутентификации должен знать об этом. Он должен отправить другой запрос на сохранение тройки user, token, ttl (туда ещё добавится internalUserId, найденное по таблице соответствия; если не найдено - ошибка).

Так же на стороне сервера авторизации необходимо удостовериться хотя бы в принадлежности номера телефона пользователю, например через OTP. Так же обязательным критерием проверки пользователя при аутентификации является номер телефона. Поскольку на момент аутентифокации в EHR сервере мы не знаем корректность связки cred, phone мы полагаемся в этом на сервер аутентификации.

В общем случае вместо номера телефона может быть другой параметр, на счет которого можно удостовериться в его принадлежности к пользователю.

На диаграме ниже показано взаимодействие пользовательского приложения, сервера авторизации и сервера мед данных.

Зачем нужна подпись аутентификации?

Допустим, что авторизационный сервер был взломан. Если бы запросы по внутреннему каналу были бы зашищены стандартным способом — по логину и паролю (например, через передачу HTTP заголовка Authorization: Basic|Bearer). В этом случае злоумышленник имел бы доступ ко всем данным всех клиник, настроенных на данный сервер авторизации.

Поскольку user_sign является частью "пароля" к EHR серверу, то злоумышленнику, чтобы получить данные конкретного пользователя нужно будет так же получить и этот параметр. Для каждого пользователя, данные которого небходимо получить. Это ограничивает возможность утечки данных до среза пользователей, для которых пользователь получил user_sign.

Примеры запросов EHR API

Сохранение сессии на стороне EHR

Данный запрос выполняется от сервера авторизации и использует внутренний канал передачи данных.

Пусть внутренние user=test_user password=test_password.

Пусть по пользователю user=user123 user_sign=user_sign_222.

Тогда хеш можно вычислить следующим образом:

echo -n test_passworduser_sign_222 | sha1sum
33b22ccec875594119f1f3c2446d822961b00170

Именно это значение должно быть передано в запросе в cred.token.

curl http://ehr-demo-api.dev.gbooking.ru -X POST -d '{"jsonrpc":"2.0","id":1,"method":"embedded_storage.save_auth_info","cred":{"user": "test_user", "token": "33b22ccec875594119f1f3c2446d822961b00170"},"params":{"authInfo":{"user":"user123","token":"token456", "ttl": 1440}}}'

Токен в системе должен быть уникален. Повторный запрос с существующим токеном вернет ошибку.

Сервер авторизации отправляет данный запрос на сторону MedMe EHR Server когда сопоставление пользователя и пациента было выполнено ранее.

Сохранение токена обмена на стороне EHR

Данный запрос выполняется от сервера авторизации и использует внутренний канал передачи данных.

Пусть внутренние user=test_user password=test_password.

Пусть exchange_token=exchtoken123.

Тогда хеш можно вычислить следующим образом:

echo -n test_passwordexchtoken123 | sha1sum
aa3c472ab7b97797e347ec345cda371663e021c8

Полученное значение хеша должно быть передано в запросе в cred.token.

curl http://ehr-demo-api.dev.gbooking.ru -X POST -d '{"jsonrpc":"2.0","id":1,"method":"embedded_storage.save_exchange_token","cred":{"user": "test_user", "token": "aa3c472ab7b97797e347ec345cda371663e021c8"},"params":{"exchangeToken":"exchtoken123","authInfo":{"user":"user456","token":"token43ge2820", "ttl": 1440}}}'

Аутентификация пользователя на EHR сервере

Данный запрос выполняется клиентским приложением.

Для успешного выполнения этого запроса в МИС должен быть пациент, удовлетворяющий требованиям параметров, переданных в запросе.

curl http://ehr-demo-api.dev.gbooking.ru -X POST -d '{"jsonrpc":"2.0","id":1,"method":"embedded_storage.authenticate","params":{"exchangeToken":"exchtoken123","patientProperties":{"name":"Alisa","surname":"Johnson","date":"2010-01-01 00:00:00.000","gender":2,"phone":"2222222222"}}}'