Содержание
OAuth PKCE
OAuth PKCE
OAuth 2.0 PKCE (ключ подтверждения для обмена кодами) позволяет общедоступным клиентским приложениям (браузерным SPA, мобильным приложениям) совершать вызовы API от имени отдельных пользователей без хранения долговременного секретного секрета сервера на стороне клиента.
Когда использовать OAuth PKCE
- Создание браузера SPA или мобильного приложения, требующего оплаты по количеству пользователей.
- Мультиарендное SaaS — каждый конечный пользователь платит за свое использование API
- Вы не можете хранить общий секретный ключ на стороне клиента (публичный клиент).
- Вам нужен отдельный отзываемый ключ для каждого пользователя (он действует, пока пользователь его не отзовёт) вместо одного общего ключа API.
Что увидят ваши пользователи
Опишите эти шаги на своём экране входа:
- В вашем приложении они выбирают «Войти через BazaarLink» (или как вы назовёте кнопку).
- Браузер открывает страницу авторизации BazaarLink. Если они ещё не вошли, сначала входят и автоматически возвращаются на эту страницу.
- Страница показывает адрес вашего приложения и что произойдёт после разрешения: для приложения создаётся новый API-ключ, использование списывается с их баланса BazaarLink, а ключ можно отозвать в любой момент. Они могут назвать ключ и задать ежемесячный лимит расходов (оба необязательно).
- Они нажимают «Разрешить» и возвращаются в ваше приложение. Если нажимают «Отклонить», ключ не создаётся, ваше приложение не уведомляется, а пользователи видят страницу «Доступ отклонён».
- Чтобы позже отозвать доступ, они открывают страницу «API-ключи» (https://bazaarlink.ai/keys) и отключают или удаляют ключ, названный по вашему приложению.
Как это работает
Шаг 1. Начать аутентификацию — Сгенерируйте случайный code_verifier (длинную случайную строку) и его хэш SHA-256 в качестве code_challenge, затем перенаправьте пользователя на страницу аутентификации BazaarLink.
https://bazaarlink.ai/auth?callback_url=https://yourapp.com/callback&code_challenge=CODE_CHALLENGE&code_challenge_method=S256Параметры URL авторизации
- callback_url (обязателен) — куда пользователь возвращается после разрешения. Правила ниже.
- code_challenge (обязателен) — SHA-256 от вашего code_verifier в кодировке base64url (43 символа, без заполнения).
- code_challenge_method (обязателен) — должен быть S256.
- state (необязателен) — ваше собственное непрозрачное CSRF-значение, от 1 до 256 печатных ASCII-символов. BazaarLink возвращает его без изменений как &state=… сразу после code. Некорректный state приводит к тому, что страница авторизации показывает "Недопустимый запрос авторизации".
- key_label (необязателен) — до 100 символов. Предзаполняет название ключа на странице согласия (пользователь по-прежнему может его изменить). Слишком длинные или пустые метки игнорируются.
- Headless tools (CLI / desktop, no callback_url) — omit callback_url. After the user allows, the page shows a one-time code (valid 5 minutes, single use) for them to enter into your tool; exchange it exactly like a redirected code. The page cannot show which app is asking, so tell users to enter the code only in a tool they started themselves.
Не поддерживается
- workspace_id и required_workspace_id — не поддерживаются. Ключ всегда принадлежит собственному аккаунту пользователя.
- code_challenge_method=plain — не поддерживается (только S256).
Правила для callback_url
- Должен быть https://. http:// принимается только для localhost, 127.0.0.1 и [::1] (любой порт); тогда страница согласия показывает предупреждение о локальной разработке.
- Без фрагмента (#), без имени пользователя и пароля в URL, не более 2048 символов.
- Страница согласия показывает имя хоста вашего callback, чтобы пользователь видел, какое приложение запрашивает доступ.
- После разрешения браузер направляется на ваш callback_url с добавленным code=… (и state=…, если вы его передали; существующая строка запроса сохраняется). Code действует 10 минут и работает один раз.
Шаг 2. Код обмена для ключа API — После того как пользователь авторизует запрос, BazaarLink перенаправляет на ваш callback_url с одноразовым code. Code действует 10 минут и может быть использован один раз; неверный code_verifier аннулирует его. Отправьте POST с code, code_verifier и code_challenge_method (обязательны все три), чтобы получить API-ключ пользователя.
Шаг 3. Используйте ключ с пользовательской областью действия — Возвращённый ключ — обычный API-ключ BazaarLink, принадлежащий авторизовавшему пользователю: использование списывается с баланса этого пользователя, а не с вашего.
curl https://bazaarlink.ai/api/v1/chat/completions \
-H "Authorization: Bearer sk-bl-..." \
-H "Content-Type: application/json" \
-d '{"model": "google/gemini-3.5-flash", "messages": [{"role": "user", "content": "Hello"}]}'Пример на JavaScript (браузер)
Страница /auth и POST /api/v1/auth/keys обслуживаются с https://bazaarlink.ai (не с api.bazaarlink.ai). Полученный ключ работает с обоими базовыми URL: https://bazaarlink.ai/api/v1 и https://api.bazaarlink.ai/v1.
Если пользователь при авторизации задаёт лимит расходов, это месячный лимит; он сбрасывается в соответствии с месячным периодом аккаунта.
Ошибки
Ошибки имеют формат в стиле OpenAI {"error":{"message","type","code"}}. POST /api/v1/auth/keys может вернуть:
- 400 invalid_code_challenge_method — code_challenge_method отсутствует, равен plain или отличается от S256.
- 400 — некорректное JSON-тело либо отсутствует code / code_verifier.
- 403 invalid_code — code неизвестен, просрочен или уже использован, code_verifier неверен, либо аккаунту больше не разрешён доступ. Во всех этих случаях намеренно возвращается одно и то же сообщение, чтобы вызывающая сторона не могла их различить. Неверный code_verifier также аннулирует code: попросите пользователя авторизоваться заново.
- 429 rate_limited — более 30 попыток обмена за 10 минут с одного IP (см. заголовок Retry-After).
- 429 key_total_cap — на аккаунте уже максимальное число API-ключей: 200.
- 405 — принимается только POST.
Создание кода с вашего сервера (ключ управления)
Владелец личного ключа управления (Management Key) может создать код авторизации напрямую через POST /api/v1/auth/keys/code, не направляя пользователя на страницу в браузере (совместим с OpenRouter). Код привязан к владельцу ключа управления, поэтому ключ, который вы получите в обмен, — это стандартный ключ в аккаунте этого владельца с лимитом, периодом, сроком действия и именем, заданными здесь. Используйте, когда ваш собственный инструмент уже держит ключ управления и хочет передать приложению ограниченный ключ. Обмен (POST /api/v1/auth/keys) такой же, как выше.
- callback_url (обязательно) и code_challenge + code_challenge_method=S256 (обязательно) — те же правила, что и для URL авторизации.
- key_label (необязательно) — до 100 символов; имя ключа. По умолчанию: "App: <ваш callback-хост>".
- limit (необязательно) — лимит расходов в USD, 0 или больше; 0 или отсутствие значения означает отсутствие лимита.
- usage_limit_type (необязательно) — daily, weekly или monthly: как часто сбрасывается лимит. Используется только вместе с limit; по умолчанию monthly.
- expires_at (необязательно) — когда истекает ключ: время ISO 8601 UTC в будущем с секундами, например 2026-12-31T23:59:59Z. Значения с точностью до минут отклоняются. Если не указано, ключ остаётся действительным, пока не будет отозван.
- workspace_id — не поддерживается (400). spawn_agent и spawn_cloud принимаются и игнорируются.
Ответ: { "data": { "id", "app_id", "created_at" } }. id — одноразовый код для обмена (действует 10 минут, один раз). В BazaarLink нет реестра приложений, поэтому app_id — это стабильное целое число, выведенное из вашего callback-адреса: один и тот же адрес всегда получает один и тот же app_id.
- 401 unauthorized — нет ключа Bearer или ключ неизвестен.
- 403 management_key_required — ключ не является личным ключом управления (стандартные ключи и ключи управления организации отклоняются).
- 403 account_not_allowed — владелец ключа заблокирован или удалён.
- 400 — invalid_callback_url, invalid_code_challenge_method, invalid_code_challenge, invalid_expires_at, workspace_not_supported или некорректное тело запроса.
- 429 rate_limited — более 30 кодов в час для одного владельца или 120 в час с одного IP (см. Retry-After).
Ключ, который вы получаете
- Стандартный API-ключ BazaarLink (sk-bl-…), такого же типа, как ключ, созданный на странице «API-ключи». Действует, пока пользователь его не отзовёт.
- Использование списывается с баланса BazaarLink пользователя. Если пользователь задал лимит расходов на странице согласия, это месячный лимит.
- Работает с обоими базовыми URL: https://bazaarlink.ai/api/v1 и https://api.bazaarlink.ai/v1.
- Учитывается в лимите аккаунта в 200 ключей и отображается в списке «API-ключи» пользователя, где его можно в любой момент отключить или удалить.
- Заблокированные или удалённые аккаунты не могут авторизовать приложения, а code, выданный до блокировки, отклоняется при обмене (403 invalid_code).
Что вы получаете
- Код авторизации + поток PKCE для общедоступных клиентских приложений
- Оплата для каждого пользователя: каждый платит за своё использование со своего баланса
- Отдельный ключ для каждого пользователя; он указан на странице «API-ключи» пользователя, где его можно отозвать