Переменные и вычисляемые поля
Связывание запросов через переменные {{name}}, экстракторы и DSL вычисляемых полей.
Многошаговые сценарии почти никогда не воспроизводятся из статичных байтов: логин возвращает сессионный токен, производную куку нужно переподписывать при каждой отправке, а nonce должен одновременно совпадать в двух местах. Диалог Replay (API lab → каталог маршрутов → Replay на запросе) при отправке подставляет шаблоны {{…}} в URL, заголовки и тело — из сохранённых переменных цепочки, из значений, извлечённых из предыдущих ответов, и из DSL выражений, который пересчитывает производные токены при каждой отправке.
Связывание запросов переменными {{name}}
Шаблон имеет вид {{name}} (пробелы внутри фигурных скобок допустимы). Имя должно соответствовать [A-Za-z_][A-Za-z0-9_.-]*. При отправке каждое вхождение в черновом URL, заголовках и теле заменяется значением.
- В диалоге Replay найдите панель Replay chain variables.
- Введите имя и значение, нажмите Add. Список чипов показывает текущие переменные; значения маскируются, пока вы не раскроете секреты.
- Сошлитесь на неё в любом редактируемом поле, например
Authorization: Bearer {{token}}или/users/{{userId}}, и запустите replay.
Переменные хранятся локально в localStorage под ключом traffic-jam:replay-variables, поэтому они переживают закрытие диалога и перезагрузку страницы и подпитывают следующий запрос в цепочке. Удалить чип можно кнопкой-корзиной.
Если у переменной, на которую есть ссылка, нет значения, шаблон остаётся на месте, а панель показывает бейдж unresolved: name; replay блокируется, пока вы не определите переменную или не уберёте ссылку.
[!NOTE] Replay по умолчанию исключает захваченные учётные данные и запрашивает подтверждение перед методами, изменяющими состояние. Переменные, которые вы вводите, считаются осознанными значениями и отправляются как есть — тестируйте только те системы, на тестирование которых у вас есть разрешение.
Извлечение значений из ответа
После завершения replay под результатом появляется панель Extract response into chain, которая сохраняет одно значение из ответа как переменную рабочей области.
| Источник | Выражение | Примечания |
|---|---|---|
| JSON path | $.access_token, $.users[0].id | Ведущий $. необязателен; [n] индексирует массивы. Нестроковые значения сериализуются в JSON. Ошибка, если тело не является JSON или путь отсутствует. |
| Заголовок | x-session-token | Регистронезависимо; трейлеры ответа тоже просматриваются. |
| Regex | "token":"([^"]+)" | Побеждает первая группа захвата; если группы нет — всё совпадение целиком. |
Выберите источник, введите выражение и имя переменной, нажмите Extract. При успехе вы получите Saved {{name}} for the next replay; переменная попадает в то же персистентное хранилище, что и добавленные вручную.
Вычисляемые поля: DSL выражений
Обычная подстановка {{name}} — это быстрый путь; всё, что сложнее внутри фигурных скобок, вычисляется как выражение над контекстом захваченного запроса в момент отправки — покрывая производные токены, которые нельзя скопировать дословно, потому что они меняются с каждым запросом.
Ссылки на поля читаются из захваченного запроса:
| Ссылка | Разрешается в |
|---|---|
cookie:name | Кука, распарсенная из захваченного заголовка Cookie (побеждает первое вхождение) |
header:name | Заголовок захваченного запроса (регистронезависимо) |
query:name | Параметр query (URL-декодированный) |
var:name | Переменная цепочки (то же, что и просто name) |
body | Текст тела захваченного запроса (пустой, если обрезано) |
Функции (несколько аргументов конкатенируются перед хешированием; для HMAC первый аргумент — ключ):
| Функция | Результат |
|---|---|
sha1(x) / sha256(x) / md5(x) | Hex-дайджест в нижнем регистре |
hmac-sha1(key, msg) / hmac-sha256(key, msg) / hmac-md5(key, msg) | HMAC в hex в нижнем регистре |
crc32(x) | Беззнаковый CRC-32 в десятичном виде; crc32() без аргумента хеширует тело |
base64(x) / base64url(x) | Стандартный / URL-safe base64 (без паддинга) |
nowMs() / nowSec() | Unix timestamp в миллисекундах / секундах |
uuid4() | Случайный UUID |
randomHex(n) | n случайных hex-символов (по умолчанию 8) |
Пайпы преобразуют значение с помощью |:
| Пайп | Действие |
|---|---|
skip:N (алиас trunc:N) | Отбросить первые N символов |
take:N (алиас prefix:N) | Оставить первые N символов |
upper / lower | Смена регистра |
urlencode | encodeURIComponent |
base64 / base64url | Закодировать значение |
Строковые литералы используют двойные кавычки с экранированием \n, \t и \\; + конкатенирует; скобки группируют. Отсутствующее поле с областью видимости вырождается в пустую строку (с ошибкой для неизвестных областей); отсутствующая обычная переменная сохраняет описанное выше поведение с маркером неразрешённости.
Именованные nonce и многооператорные шаблоны
Операторы, разделённые ;, выполняются по порядку; результат — значение последнего оператора. Присваивание name = expr сохраняет локальную переменную на одну отправку — это способ сгенерировать nonce один раз и переиспользовать его, поскольку один вычисляемый контекст разделяется между всеми полями replay (URL, заголовки и тело видят одни и те же локальные переменные):
{{ p = randomHex:4; p + sha1(secret + cookie:session + p) | skip:4 }}
Второе поле, ссылающееся на {{ p }} в той же отправке, получит идентичный nonce. Локальные переменные затеняют переменные цепочки с тем же именем. randomHex:N и randomB64:N также работают как генераторы с областью видимости (randomHex:4 → 4 hex-символа; randomB64:8 → base64 из 8 случайных байт).
Если вычисление не удаётся (неизвестная функция, пайп или область видимости), шаблон остаётся нетронутым, а ошибка проявляется как Computed field error: …, блокируя отправку.
Разобранный пример: производная кука fgssc
Конструкция из реальной практики: кука fgssca-goldapple — это случайный префикс из 4 hex-символов, за которым следует sha1(appSecret + gsscCookie + prefix) с отброшенными первыми 4 hex-символами. Чтобы воспроизвести её, добавьте секрет приложения как переменную цепочки (например, fgsscSecret), затем поместите это в черновой заголовок Cookie как значение fgssca-goldapple:
{{ p = randomHex:4; p + sha1(fgsscSecret + cookie:gssca-goldapple + p) | skip:4 }}
Результат — 40 hex-символов: префикс из 4 символов плюс обрезанный SHA-1. Поскольку p — именованная локальная переменная, любое другое поле, которому нужен тот же префикс, может сослаться на {{ p }}.
[!TIP] Пока не знаете формулу? Вкладка Signature в API lab перебором находит именно этот класс —
prefix + hash(secret + <field> + prefix)[dropN:]наряду с классическими каноникализациями — и сообщает входные данные вывода. См. /docs/ru/api-re/.
Локальные примитивы хеширования
DSL вычисляется синхронно внутри построения payload, поэтому не может вызывать WebCrypto. Хеши работают на локальных синхронных реализациях — SHA-1/SHA-256 по FIPS 180-4, HMAC по RFC 2202/4231 и локальные MD5/HMAC-MD5 (WebCrypto не включает MD5, который всё ещё используют легаси-схемы подписывания в мобильных приложениях) — проверенных на стандартных тестовых векторах. Ничего не покидает рабочую область для вычисления подписи, и та же логика вывода экспортируема в автономный Go-коллектор; см. /docs/ru/collector/. Маскирование значений в панели переменных следует настройке раскрытия рабочей области — см. /docs/ru/security/.
Replay-верстак, лимиты батчей, управление TLS-отпечатком и mTLS описаны в /docs/ru/replay/.