Виджет / HMAC examples
HMAC visitor token — примеры на популярных стэках
Готовые сниппеты эндпоинта /api/supporthub/token для FastAPI, Django, Flask, Express, Next.js API, Laravel, Rails, Go, .NET и Spring Boot. Полный референс с форматом payload, ротацией и edge-кейсами — в /docs/widget/hmac.
Что нужно сделать
- Получить workspace-секрет один раз и положить в env вашего бэкенда:http
GET /api/v1/widget/signing-secret Authorization: Bearer sk_xxx 200 OK { "secret": "wsig_..." } - Реализовать у себя эндпоинт
GET /api/supporthub/tokenпо одному из шаблонов ниже. Эндпоинт должен:- аутентифицировать текущего пользователя (через session-cookie / JWT / что угодно);
- взять стабильный
user_id(PK из вашей БД, slug, и т.д.); - собрать payload
{"user_id": "...", "exp": <unix>}; - подписать raw JSON-байты через HMAC-SHA256;
- вернуть
{ "token": "<base64url(payload)>.<hex(sig)>" }.
- Раскомментировать
fetch-блок в установочном скрипте. Виджет автоматически передаст токен бэку SupportHub какdata-visitor-token.
Примеры реализации
Все примеры используют HMAC-SHA256 поверх raw JSON-байт (не base64-строки), base64url-кодирование payload без padding-знака =, и компактный JSON без пробелов (separators=(",", ":") или эквивалент). TTL — 1 час; делайте по вкусу, но не вечно.
app/api/supporthub.pypython
import base64, hashlib, hmac, json, os, time
from fastapi import APIRouter, Depends, HTTPException
router = APIRouter()
SECRET = os.environ["SUPPORTHUB_SIGNING_SECRET"].encode()
@router.get("/api/supporthub/token")
async def supporthub_token(current_user = Depends(get_current_user)):
if not current_user:
raise HTTPException(401, "Unauthorized")
payload = json.dumps(
{"user_id": str(current_user.id), "exp": int(time.time()) + 3600},
separators=(",", ":"),
).encode()
sig = hmac.new(SECRET, payload, hashlib.sha256).hexdigest()
payload_b64 = base64.urlsafe_b64encode(payload).rstrip(b"=").decode()
return {"token": f"{payload_b64}.{sig}", "expires_in": 3600}Тестовый прогон без бэкенда
Если хотите подёргать API руками до прикручивания эндпоинта — подпишите payload, например, в Python REPL и положите в HTML атрибутом data-visitor-token:
python
import base64, hashlib, hmac, json, time
SECRET = "wsig_..." # ваш workspace-секрет
payload = json.dumps(
{"user_id": "demo-42", "exp": int(time.time()) + 3600},
separators=(",", ":"),
).encode()
sig = hmac.new(SECRET.encode(), payload, hashlib.sha256).hexdigest()
print(base64.urlsafe_b64encode(payload).rstrip(b"=").decode() + "." + sig)html
<script async
src="https://support.forestsnet.com/widget-bundle?ws=YOUR_WS"
data-visitor-token="ВЫВОД_ИЗ_PYTHON_ВЫШЕ"></script>Дальше
- Полный референс HMAC — формат payload, валидация на бэке SupportHub, ротация секрета, edge-кейсы (просрочка, подмена, дрейф clock).
- Identify посетителей — что отдавать в
data-*рядом с токеном (имя, email, attrs). - Troubleshooting — почему 401 от SupportHub, почему виджет ушёл в anonymous fallback, как проверить подпись.
Была ли страница полезной?