Перейти к основному содержимому
Версия: 7.0

Ротация API-токенов

Назначение

Начиная с Пассворка 7.6.0, для API добавлены два новых эндпоинта, позволяющие обновлять отдельно accessToken или отдельно refreshToken. Вместе с существующим эндпоинтом POST /api/v1/sessions/refresh, который ротирует пару токенов, теперь доступны три эндпоинта для ротации при работе через API-сессии. Это относится и к сессиям сервисных учётных записей, создаваемых при генерации API-токенов.

СпособЭндпоинтЧто меняется после успешного ответа
Ротация API-парыPOST /api/v1/sessions/refreshНовые accessToken и refreshToken. Прежняя пара недействительна.
Ротация accessTokenPOST /api/v1/sessions/refresh-access-tokenНовый accessToken. refreshToken без изменений.
Ротация refreshTokenPOST /api/v1/sessions/refresh-refresh-tokenНовый refreshToken. accessToken без изменений до своего срока.

Общие сведения

Эндпоинты refresh-access-token и refresh-refresh-token рассчитаны на сессии с типом клиента API. Бэкенд не различает учётную запись и сервисную учётную запись — важен только тип сессии. Классический POST /api/v1/sessions/refresh используется для обновления пары токенов в общем сценарии (в т.ч. после ответа accessTokenExpired).

По умолчанию Пассворк отдаёт ответы API в Base64. Чтобы получать JSON в теле ответа, добавьте заголовок X-Response-Format: raw. Подробнее о формате ответа в общем описании.

Поля accessTokenExpiredAt и refreshTokenExpiredAt — время истечения в Unix time. В ответе приходит только то поле, которое относится к обновлённому токену (или оба поля при ротации пары).

Ротация пары: POST /api/v1/sessions/refresh

Выдаётся новая пара accessToken и refreshToken. После успеха старая API-пара недействительна. Типичный сценарий: ответ 401 с кодом accessTokenExpired — клиент отправляет текущие токены и получает новую пару.

Пример запроса

curl -s --request POST \
--url "https://passwork.example.com/api/v1/sessions/refresh" \
--header 'Content-Type: application/json' \
--header 'X-Response-Format: raw' \
--header "Authorization: Bearer 7FmKp2nQ8vRt3WxYz9Bc1Dg4Hj6Lo5Ns0Ue+SmVaXoI=" \
--data "{\"refreshToken\": \"2XkQp3oR9wSu4VyZa0Cd2Eh5Ik7Mp6Ot1Vf+TnWbYpJ=\"}" | jq .

Пример ответа

{
"accessToken": "9GnLq4pS0xTv5WzAb1De3Fi6Jl8Nq7Pu2Wg+UoXcZqK=",
"refreshToken": "0HoMr5qT1yUw6XaBc2Ef4Gj7Km9Or8Qv3Xh/VpYdArL=",
"accessTokenExpiredAt": 1775814596,
"refreshTokenExpiredAt": 1782990596
}

Поведение

  1. По паре заголовка Authorization и тела с refreshToken определяется сессия.
  2. Выдаётся новая API-пара. Предыдущая становится недействительной.

Ротация accessToken: POST /api/v1/sessions/refresh-access-token

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

Пример запроса

curl -s --request POST \
--url "https://passwork.example.com/api/v1/sessions/refresh-access-token" \
--header 'Content-Type: application/json' \
--header 'X-Response-Format: raw' \
--data "{\"accessToken\": \"JpNs6rWa2bXc8YdZ0ePq4fGh5Ij1Kl+Mn7Ro9StUvWx=\"}" | jq .

Пример ответа

{
"accessToken": "KqOt7sXb3cYd9ZeA1fQr5gHi6Jk2Lm+No8Sp0TuVwXy=",
"accessTokenExpiredAt": 1775820103
}

Поведение

  1. По хешу accessToken определяется сессия.
  2. Сессия не удалена, срок refreshToken не истёк, тип клиента — API.
  3. accessToken на момент запроса не должен быть просрочен.
  4. Выдаётся новый accessToken. Старый после успеха недействителен.

Ротация refreshToken: POST /api/v1/sessions/refresh-refresh-token

Новый refreshToken, текущий accessToken остаётся действительным до своего срока. Для политики ротации долгоживущего refreshToken без инвалидации уже выданного accessToken.

Пример запроса

curl -s --request POST \
--url "https://passwork.example.com/api/v1/sessions/refresh-refresh-token" \
--header 'Content-Type: application/json' \
--header 'X-Response-Format: raw' \
--data "{\"refreshToken\": \"LrPu8tYc4dZe0AfB2gRs6hJk7Kl3Mn+Op9Tq1UvWxYz=\"}" | jq .

Пример ответа

{
"refreshToken": "MsQv9uZd5eAf1BgC3hSt7iKl8Lm4No+Pq0Ur2VwXzA0=",
"refreshTokenExpiredAt": 1782999124
}

Поведение

  1. По хешу refreshToken определяется сессия.
  2. Сессия не удалена, refreshToken не истёк, тип клиента — API.
  3. Выдаётся новый refreshToken. Старый после успеха недействителен.