Генерация ключа API пользователя без его подтверждения

Я использую Discourse в режиме headless и могу получать информацию о пользователях с помощью ключа API администратора, однако мне порекомендовали вместо этого генерировать пользовательский API-ключ для каждого пользователя. Поэтому я пытаюсь реализовать именно этот метод, но не хочу, чтобы пользователю приходилось переходить в новый интерфейс для «одобрения» создаваемого для него ключа API.

Мое решение — программно отправить подтверждение. При GET-запросе к ‘/user-api-key/new’ я могу извлечь данные элемента ‘form’, но не могу отправить POST-запрос к ‘/user-api-key/’, так как получаю ошибку CSRF.

Я отключил защиту от CSRF для Discourse Connect, но есть ли аналогичная настройка для api-key?
SiteSetting.discourse_connect_csrf_protection

Если нет, то я не буду использовать пользовательские ключи API, пока не смогу создавать их без прерывания работы через интерфейс.

Заранее спасибо!

Кажется, существовало решение, которое могло бы сработать в предыдущих версиях, но я не вижу его обновленной версии:

Возможно, мы строим одно и то же :slight_smile:, хотя мой вариант лишь отчасти headless.

Подозреваю, что нет, и это сделано намеренно.

Я тоже об этом задумывался, но в моём случае, думаю, это не станет проблемой — я не пытаюсь скрыть Discourse.

Одно важное замечание: лимиты скорости (rate limits) по умолчанию различаются для пользовательских API-ключей и административных ключей «для всех пользователей»:
Available settings for global rate limits and throttling.

Лимиты для пользовательского API:
DISCOURSE_MAX_USER_API_REQS_PER_MINUTE: по умолчанию 20
DISCOURSE_MAX_USER_API_REQS_PER_DAY: по умолчанию 2880

Лимиты для административного API:
DISCOURSE_MAX_ADMIN_API_REQS_PER_MINUTE: 60

Если ваше приложение подключается к самостоятельно размещённому экземпляру Discourse, вы, скорее всего, сможете переопределить лимиты для административного API. Если же подключение идёт к хостинговым экземплярам Discourse, лимиты для пользовательского API предлагают гораздо больше гибкости. При использовании лимитов административного API вам в итоге придётся помещать все запросы в очередь с ограничением скорости.

Редактирование: вместо использования спецификации пользовательских API-ключей для генерации ключей можно использовать административный API-ключ для создания пользовательских API-ключей. Это решает проблему необходимости одобрения приложения пользователем.

Обратите внимание: приведённый ниже ключ относится к моему локальному домену (localhost), поэтому его публикация не представляет риска.

Неэкранированные параметры ключа: {key:description:sally} {key:username:sally} {key:scopes:[scope_id:topics:write]} {key:scopes:[key:write]} {key:scopes:[name:write]} {key:scopes:[params:[topic_id]]} {key:scopes:[urls:[/posts (POST)]]} {key:scopes:[selected:true]}

❯ curl -X POST "http://localhost:4200/admin/api/keys" \
      -H "Api-Key: $api_key" \
      -H "Api-Username: system" \
      -H "Content-Type: application/json" \
      -d $json
{"key":{"id":29,"key":"f5c6307b51dd2882bde525dc9775fe7504b55c93fa40177b650f9e6b77a9d25b","truncated_key":"f5c6","description":"sally","last_used_at":null,"created_at":"2024-06-02T00:44:19.944Z","updated_at":"2024-06-02T00:44:19.944Z","revoked_at":null,"user":{"id":3,"username":"sally","avatar_template":"/user_avatar/127.0.0.1/sally/{size}/58_2.png"},"api_key_scopes":[{"resource":"topics","action":"write","parameters":["topic_id"],"urls":["/posts (POST)"],"allowed_parameters":{},"key":"write"}]}}

В любом случае у вас остаётся API-ключ, который каким-то образом нужно управлять. Я предполагаю, что он должен быть зашифрован и сохранён в базе данных.

Вы используете React на фронтенде? Я открыт к сотрудничеству, чтобы сократить дублирование и повысить надёжность кода. Мне кажется, что самая сложная часть — это аутентификация через SSO. Так что, надеюсь, дальше всё пойдёт как по маслу.

Да, это приложение на базе Remix и React Router. То есть React на фронтенде, Node.js на бэкенде.

Я работаю с этим уже много лет. Напишите мне здесь, если у вас возникнут вопросы.

Я пытаюсь создать решение, которое корректно работает с ограничениями скорости для размещённых сайтов на Discourse. Это оказалась самая сложная часть. Ключи API пользователей казались возможным способом решения проблемы, но есть также ограничение скорости по IP-адресу, поэтому я вернулся к использованию одного ключа API и очередям для всех запросов к API.