Начало работы
Аутентификация
Доступ к API выдаётся парой JWT-токенов: коротким access_token для запросов и refresh_token для его обновления.
СхемаJWT, заголовок Authorization: Bearer <access_token>
ВходGET /auth/login-token
ОбновлениеPOST /auth/refresh
Время жизни access_token1 минута
Время жизни refresh_token30 дней
refresh_tokenОдноразовый: заменяется новым при каждом обновлении
Как это работает
- Обратитесь по ссылке входа с параметрами
idиtoken— в ответ придёт пара токенов. - Подставляйте
access_tokenв заголовокAuthorizationпри каждом запросе к/api/*. - Когда
access_tokenистёк, получите новую пару методом/auth/refreshи повторите запрос.
Получение токенов
Точка входа: постоянные id и token обмениваются на пару JWT.
GET
http://192.168.70.253:3102/auth/login-token| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
id | string (uuid) | да | Идентификатор пользователя. |
token | string | да | Постоянный токен пользователя. |
curl 'http://192.168.70.253:3102/auth/login-token?id=<id>&token=<token>'const params = new URLSearchParams({ id: '<id>', token: '<token>' })
const response = await fetch('http://192.168.70.253:3102/auth/login-token?' + params)
const { result } = await response.json()
const { access_token: accessToken, refresh_token: refreshToken, expires_in: expiresIn } = resultimport requests
response = requests.get(
'http://192.168.70.253:3102/auth/login-token',
params={'id': '<id>', 'token': '<token>'},
timeout=30,
)
response.raise_for_status()
tokens = response.json()['result']
access_token = tokens['access_token']
refresh_token = tokens['refresh_token']<?php
$query = http_build_query(['id' => '<id>', 'token' => '<token>']);
$ch = curl_init('http://192.168.70.253:3102/auth/login-token?' . $query);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$tokens = json_decode(curl_exec($ch), true)['result'];
curl_close($ch);
$accessToken = $tokens['access_token'];
$refreshToken = $tokens['refresh_token'];Соединение = Новый HTTPСоединение("192.168.70.253", 3102, , , , 30);
Запрос = Новый HTTPЗапрос("/auth/login-token?id=<id>&token=<token>");
Ответ = Соединение.ВызватьHTTPМетод("GET", Запрос);
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
Токены = ПрочитатьJSON(Чтение)["result"];
Чтение.Закрыть();
ТокенДоступа = Токены["access_token"];
ТокенОбновления = Токены["refresh_token"];| Поле ответа | Тип | Обязательный | Описание |
|---|---|---|---|
success | boolean | да | Признак успешного ответа. Приходит во всех ответах API рядом с result. |
result | Tokens | да | Полезная нагрузка ответа. Все ответы API обёрнуты в это поле. |
| Свойство | Тип | Обязательный | Описание |
|---|---|---|---|
access_token | string (JWT) | да | Токен для заголовка Authorization. |
refresh_token | string (JWT) | да | Токен для получения новой пары без повторного входа. |
expires_in | number | да | Время жизни access_token в секундах. |
200 OK
{
"success": true,
"result": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 60
}
}Использование токена
Все методы раздела /api требуют заголовок Authorization.
| Заголовок | Тип | Обязательный | Описание |
|---|---|---|---|
Authorization | string | да | Bearer <access_token>. Без него запрос к /api/* вернёт 401. |
GET
http://192.168.70.253:3102/api/vin?vin=JTJBERBZ602000192GET
http://192.168.70.253:3102/api/q?q=702c9916-428a-433d-8eac-2245d9a48834curl 'http://192.168.70.253:3102/api/vin?vin=JTJBERBZ602000192' \
-H 'Authorization: Bearer <access_token>'const response = await fetch('http://192.168.70.253:3102/api/vin?vin=JTJBERBZ602000192', {
headers: { Authorization: 'Bearer <access_token>' }
})
if (response.status === 401) {
// access_token истёк — обновите пару через /auth/refresh и повторите запрос
}
const data = await response.json()import requests
response = requests.get(
'http://192.168.70.253:3102/api/vin',
params={'vin': 'JTJBERBZ602000192'},
headers={'Authorization': f'Bearer {access_token}'},
timeout=30,
)
if response.status_code == 401:
access_token = refresh(refresh_token)
data = response.json()<?php
$ch = curl_init('http://192.168.70.253:3102/api/vin?vin=JTJBERBZ602000192');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $accessToken],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
$data = json_decode($body, true);Соединение = Новый HTTPСоединение("192.168.70.253", 3102, , , , 30);
Заголовки = Новый Соответствие;
Заголовки.Вставить("Authorization", "Bearer " + ТокенДоступа);
Запрос = Новый HTTPЗапрос("/api/vin?vin=JTJBERBZ602000192", Заголовки);
Ответ = Соединение.ВызватьHTTPМетод("GET", Запрос);
Если Ответ.КодСостояния = 401 Тогда
ТокенДоступа = ОбновитьТокен(ТокенОбновления);
КонецЕсли;Обновление токена
Возвращает новую пару токенов в том же формате, что и вход, со статусом 201 Created.
POST
http://192.168.70.253:3102/auth/refresh| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
refresh_token | string (JWT) | да | Токен обновления, полученный при входе или при прошлом обновлении. |
curl -X POST 'http://192.168.70.253:3102/auth/refresh' \
-H 'Content-Type: application/json' \
-d '{ "refresh_token": "<refresh_token>" }'const response = await fetch('http://192.168.70.253:3102/auth/refresh', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ refresh_token: refreshToken })
})
const { result: tokens } = await response.json()import requests
response = requests.post(
'http://192.168.70.253:3102/auth/refresh',
json={'refresh_token': refresh_token},
timeout=30,
)
response.raise_for_status()
tokens = response.json()['result']<?php
$ch = curl_init('http://192.168.70.253:3102/auth/refresh');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode(['refresh_token' => $refreshToken]),
]);
$tokens = json_decode(curl_exec($ch), true)['result'];
curl_close($ch);Соединение = Новый HTTPСоединение("192.168.70.253", 3102, , , , 30);
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/json");
Тело = Новый Структура("refresh_token", ТокенОбновления);
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, Тело);
Запрос = Новый HTTPЗапрос("/auth/refresh", Заголовки);
Запрос.УстановитьТелоИзСтроки(ЗаписьJSON.Закрыть(), КодировкаТекста.UTF8,
ИспользованиеByteOrderMark.НеИспользовать);
Ответ = Соединение.ВызватьHTTPМетод("POST", Запрос);
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
Токены = ПрочитатьJSON(Чтение)["result"];
Чтение.Закрыть();| Поле ответа | Тип | Обязательный | Описание |
|---|---|---|---|
success | boolean | да | Признак успешного ответа. Приходит во всех ответах API рядом с result. |
result | Tokens | да | Полезная нагрузка ответа. Все ответы API обёрнуты в это поле. |
201 Created
{
"success": true,
"result": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 60
}
}refresh_token одноразовый
После успешного обновления прежний refresh_token перестаёт действовать. Сохраните оба токена из ответа и используйте для следующего обновления новый refresh_token: повторный вызов /auth/refresh со старым токеном вернёт 401.
Ошибки
Тело ответа при отказе приходит без обёртки result.
| HTTP | Код ошибки | Когда возникает |
|---|---|---|
| 401 | Unauthorized | Заголовок Authorization не передан, access_token истёк или повреждён. Нужно обновить пару через /auth/refresh. |
| 401 | Unauthorized | Ответ /auth/refresh: refresh_token истёк, отозван или уже использован. Нужно пройти вход по ссылке заново. |
| Поле тела ошибки | Тип | Обязательный | Описание |
|---|---|---|---|
statusCode | number | да | HTTP-код ответа, дублирует статус. |
timestamp | string | да | Момент отказа в формате ISO 8601. |
path | string | да | Путь запроса без базового адреса. |
method | string | да | HTTP-метод запроса. |
message | string | да | Причина отказа, например Unauthorized. |
401 Unauthorized
{
"statusCode": 401,
"timestamp": "2026-09-01T11:19:15.591Z",
"path": "/api/vin",
"method": "GET",
"message": "Unauthorized"
}Дополнительная информация
Ссылка входа — это секрет
Пара id и token постоянна и даёт полный доступ к API. Держите её на сервере: не публикуйте в браузерном коде, мобильных приложениях и репозиториях.
- Храните пару токенов вместе: без
refresh_tokenпридётся заново проходить вход. - После каждого обновления заменяйте сохранённую пару целиком:
refresh_tokenодноразовый и приходит новым в каждом ответе. - Срок жизни
refresh_token— 30 дней с момента выдачи. Если приложение простаивало дольше, обновление вернёт 401 и понадобится повторный вход. - Рабочая стратегия: держите токен с меткой
expires_inи обновляйте его за несколько секунд до истечения, а на ответ 401 — обновляйте пару и повторяйте запрос один раз. - Если
/auth/refreshтоже ответил ошибкой, повторите вход по/auth/login-token— постоянныеidиtokenдля этого и нужны.