# API: аутентификация


## Коллекции для Postman {#postman-collections}
- [Аутентификация по ЭЦП](../%D0%90%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F%20%D0%BF%D0%BE%20%D0%AD%D0%A6%D0%9F.postman_collection.json)


***
## `POST` `/api/auth` - аутентификация, подготовительный этап - получение блока случайных данных {#auth-init}
Аутентификация основана на подписании пользователем блока случайных данных полученных от сервиса. Подготовительный этап заключается в передаче сервису запроса на новый блок случайных данных.

**Важно!** Каждый блок случайных данных может быть использован только один раз и имеет ограниченный срок действия.

Вопросы интеграции аутентификации по цифровым сертификатам в информационные системы освещены в заметке [Аутентификация по цифровым сертификатам](/kk/blog/authentication/)

[Попробовать этот API в Postman](#postman-collections)

Запрос (`Content-Type` необходимо установить в `application/json`):
```json
{
}
```

Ответ:
```json
{
  "nonce": "base64_encoded_nonce"
}
```

- `nonce` - блок случайных данных в *base64*.


***
## `POST` `/api/auth` - аутентификация {#auth}
Для выполнения аутентификации необходимо передать сервису цифровую подпись ранее полученного блока случайных данных. В том случае, если проверка подписи сервисом пройдет успешно, пользователь будет идентифицирован по данным содержащемся в его сертификате.

Поддерживается два режима работы:
- внутренняя аутентификация для нужд сервиса SIGEX;
- внешняя аутентификация для нужд сторонней информационной системы.

В режиме **внутренней аутентификации** для хранения информации об аутентификации используется *cookie* (`Secure`, `HttpOnly` и `SameSite=Strict`) с именем `jwt` в котором хранятся данные о прошедшем аутентификацию пользователе в формате [JWT](https://tools.ietf.org/html/rfc7519). Полезная нагрузка *JWT* токена содержит информацию, необходимую для идентификации пользователя.

При обращении к защищенным API сервис проверяет наличие в заголовках запроса *cookie* `jwt` и на основании данных в *JWT* токене принимает решение об авторизации.

В рамках обработки всех API выполняется проверка оставшего времени жизни *JWT* токена в *cookie* `jwt` и, при необходимости, его обновление. Новый *JWT* токен передается в ответе в *cookie* `jwt`.

Так же в режиме **внутренней аутентификации** в SIGEX будет создан профиль с настройками нового пользователя.

В режиме **внешней аутентификации** никаких *cookie* не устанавливается и профилей не создается, сторонняя информационная система получает ответ с данными сертификата которые она может использовать для авторизации (принятия решения о предоставлении пользователю прав доступа в систему).

Вопросы интеграции аутентификации по цифровым сертификатам в информационные системы освещены в заметке [Аутентификация по цифровым сертификатам](/kk/blog/authentication/)

Поддерживаются два типа подписей:
- CMS - можно получить у *NCALayer* методом *sign* нового модуля *kz.gov.pki.knca.basics*;
- XML - можно получить у *NCALayer* методом *sign* нового модуля *kz.gov.pki.knca.basics*.

JS библиотека с открытым исходным кодом [https://github.com/sigex-kz/ncalayer-js-client](https://github.com/sigex-kz/ncalayer-js-client) поддерживает все эти варианты.

CMS подписи поддерживаются в DER и PEM кодировках.

[Попробовать этот API в Postman](#postman-collections)

Запрос (`Content-Type` необходимо установить в `application/json`):
```json
{
  "nonce": "base64_encoded_nonce",
  "signature": "signature",
  "external": true
}
```
- `nonce` - блок случайных данных в *base64* полученный от сервиса на подготовительном этапе;
- `signature` - в случае CMS это должна быть подпись в кодировке DER дополнительно закодированная в *base64*, либо в кодировке PEM без дополнительного кодирования, в случае XML - текстовое представление XML;
- `external` - опциональное поле, позволяет установить режим внешней аутентификации, по умолчанию `false`.

Ответ:
```json
{
  "userId": "IIN1234567890AB",
  "businessId": "BIN1234567890AB",
  "email": "user@example.com",
  "subject": "SERIALINUMBER=IIN1234567890AB,CN=User",
  "subjectStructure": [
    [
      {
        "oid": "2.5.4.5",
        "name": "SERIALINUMBER",
        "valueInB64": false,
        "value": "IIN1234567890AB"
      }
    ],
    [
      {
        "oid": "2.5.4.3",
        "name": "CN",
        "valueInB64": false,
        "value": "User"
      }
    ]
  ],
  "subjectAltName": "rfc822Name=user@example.com",
  "subjectAltNameStructure": [
    {
      "type": "rfc822Name",
      "value": "user@example.com"
    }
  ],
  "signAlgorithm": "1.2.840.113549.1.1.11",
  "keyStorage": "1.2.398.3.3.5.1.1",
  "policyIds": ["OID.0","OID.1"],
  "extKeyUsages": ["OID.0","OID.1"],
  "certificateValidFrom": 1535622190000,
  "certificateValidUntil": 1630120980000
}
```

- `userId` - ИИН пользователя прошедшего аутентификацию;
- `businessId` - БИН пользователя прошедшего аутентификацию, доступен только в случае использования сертификата юридического лица;
- `email` - адрес электронной почты из `subject`, либо из `subjectAltName`, поле может отсутствовать в том случае, если электронная почта не указана (опциональное поле);
- `subject` - имя владельца (Subject) сертификата сформированное в соответствии с [RFC 4514](https://tools.ietf.org/html/rfc4514);
- `subjectStructure` - структурированное представление имени владельца (Subject) сертификата;
- `subjectAltName` - альтернативное имя владельца сертификата в соответствии с RFC 4514 (опциональное поле);
- `subjectAltNameStructure` - структурированное представление альтернативного имени владельца сертификата (опциональное поле);
- `signAlgorithm` - OID алгоритма подписи;
- `keyStorage` - OID типа хранилища (опциональное поле);
- `policyIds` - массив OID-ов политик использования сертификата;
- `extKeyUsages` - массив OID-ов расширенного использования ключа;
- `certificateValidFrom` - начало срока действия сертификата;
- `certificateValidUntil` - окончание срока действия сертификата.

Структурированное представление имени владельца (Subject) сертификата - это массив, содержащий набор `RDN`, каждый из которых, в свою очередь, является массивом аттрибутов. Представление основывается на структуре поля Subject сертификата, описанного в [RFC 5280](https://tools.ietf.org/html/rfc5280#section-4.1.2.4).

Каждый атрибут представлен в виде объекта:
```json
{
  "oid": "2.5.4.3",
  "name": "CN",
  "valueInB64": false,
  "value": "User CommonName",
}
```

- `oid` - объектный идентификатор типа атрибута;
- `name` - текстовое представление типа атрибута в соответствии со структурами регистрационных свидетельств (сертификатов) описанных в документе "Правила применения регистрационных свидетельств НУЦ РК" доступного на портале НУЦ РК в разделе [Документация](https://pki.gov.kz/documentation/);
- `valueInB64` - флаг, определяющий является ли значение в поле `value` строкой, либо *base64* представлением бинарных данных;
- `value` - значение атрибута, значения некоторых атрибутов не могут быть представлены в текстовом виде, в этом случае в это поле будет записано *base64* представление бинарного значения атрибута и `valueInB64` будет установлен в `true`.


***
## `POST` `/api/auth` - сброс аутентификации {#auth-reset}
Технически сброс аутентификации заключается в возврате *cookie* с именем `jwt` с пустым значением, атрибутом `Max-Age` установленным в `0` и атрибутом `Expires` содержащим дату до текущей даты. Ожидаемая реакция совместимого браузера заключается в удалении *cookie* с именем `jwt` из локального хранилища.

Запрос (`Content-Type` необходимо установить в `application/json`):
```json
{
  "logout": true
}
```
- `logout` - должно быть установлено в `true`.

Ответ:
```json
{
}
```


***
## `GET` `/api/auth` - текущее состояние аутентификации {#auth-status}
В случае том случае, если аутентификация пройдена и в заголовках запроса присутствовал *cookie* `jwt`, то ответ будет идентичен тому, который возвращает [`POST` `/api/auth` - аутентификация](/kk/support/developers/api-auth/index.md#auth).


***
## `GET` `/api/authLog` - журнал аутентификации {#auth-log}
Возвращает информацию о последних зарегистрированных событиях аутентификации выполнившего вход пользователя.

Ответ:
```json
{
  "userId": "IIN012345678901",
  "businessId": "BIN9876543212098",
  "eventsTotal": 3,
  "events": []
}
```

- `userId` - ИИН выполнившего вход пользователя;
- `businessId` - БИН организации, чьим сотрудником является выполнивший вход пользователь, доступен только в случае использования для аутентификации сертификата сотрудника юридического лица;
- `eventsTotal` - количество событий в журнале;
- `events` - массив объектов описывающих события аутентификации.

Структура объекта описывающего событие аутентификации:
```json
{
  "authAt": 1585827107000,
  "serialNumber": "4beb939d4fb14b047f3bcddf3881eb2ff9acbeb5",
  "issuer": "CN=ҰЛТТЫҚ КУӘЛАНДЫРУШЫ ОРТАЛЫҚ (GOST) 2022,C=KZ",
  "ip": "1.1.1.1"
}
```

- `authAt` - время регистрации события аутентификации в миллисекундах с UNIX Epoch;
- `serialNumber` - серийный номер сертификата, использованного для аутентификации;
- `issuer` - DN имя издателя сертификата, использованного при аутентификации;
- `ip` - IP адрес с которого выполнялась аутентификация.

