Интеграции

Единый вход (SSO)

Читатели, вошедшие на ваш сайт, автоматически входят и в комментарии. Без второго аккаунта и без второго входа.

Как это работает

  1. Пока читатель авторизован на вашем сайте, ваш сервер подписывает короткоживущий токен, в котором сказано, кто он.
  2. Страница передаёт этот токен виджету комментариев в атрибуте sso-token.
  3. Crowment проверяет подпись и авторизует читателя в комментариях под этой личностью.

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

1. Включите его

Откройте Site Console → ваш виджет → Single Sign-On. Менять настройки могут владельцы и администраторы.

Создайте секрет подписи

Это может сделать только владелец виджета. Секрет показывается один раз: сохраните его в переменных окружения сервера, например как CROWMENT_SSO_SECRET. Никогда не размещайте его в коде для браузера, в сборке приложения или в публичном репозитории.

Выберите режим

  • Off: читатели входят только через Crowment.
  • Optional: читатели, вошедшие на ваш сайт, авторизуются автоматически; вход через Crowment остаётся доступным.
  • Required: войти могут только аккаунты вашего сайта. Существующие комментарии и сессии сохраняются.

Укажите страницы входа и выхода (необязательно)

Обе должны находиться на домене виджета. Кнопка входа в виджете отправляет читателей на вашу страницу входа с параметром return_to, в котором указана страница, откуда они пришли. Перед перенаправлением убедитесь, что return_to ведёт на ваш собственный сайт.

2. Подпишите токен на сервере

При каждом просмотре страницы авторизованным читателем подписывайте JWT алгоритмом HS256 своим секретом.

ClaimОбязательноЗначение
subдаID пользователя на вашем сайте в виде строки, не длиннее 128 символов. Используйте ID, который никогда не меняется и не переиспользуется; адрес email — плохой выбор.
nameдаИмя рядом с комментариями, до 100 символов. HTML удаляется.
avatarнетURL изображения с https://. Всё остальное игнорируется.
badgesнетКлючи значков читателя, например ["vip"], совпадающие с SSO-ключами в разделе Badges. Если не передать, значки не меняются; [] снимает значки, выданные этим способом. Значки, выданные в панели, остаются.
audдаApp key вашего виджета — точно как в коде встраивания.
iat, expдаВремя выпуска и истечения в секундах. Токен живёт не дольше часа. Допускается расхождение часов в одну минуту.

Claim email не нужен и не используется: Crowment никогда не сопоставляет аккаунты по email.

// npm install jsonwebtoken
import jwt from 'jsonwebtoken'

const ssoToken = jwt.sign(
  { sub: String(user.id), name: user.displayName, avatar: user.avatarUrl },
  process.env.CROWMENT_SSO_SECRET,
  { algorithm: 'HS256', audience: CROWMENT_APP_KEY, expiresIn: '1h' },
)

3. Передайте токен виджету

На страницах, которые рендерит сервер, поместите токен в код встраивания:

<script defer src="https://embeds.crowment.com/comments.js"></script>

<!-- signed in: pass the token your backend signed for this page view -->
<crow-comments app-key="YOUR_APP_KEY" sso-token="SIGNED_TOKEN"></crow-comments>

<!-- signed out: leave sso-token out -->
<crow-comments app-key="YOUR_APP_KEY"></crow-comments>

Передавайте токен на каждой странице, где читатель авторизован. Страница без токена сообщает виджету, что читатель вышел, и виджет выходит из комментариев тоже. Переходы по страницам не приводят к повторному входу каждый раз: виджет сохраняет сессию и обменивает новый токен только при смене читателя.

В одностраничном приложении добавляйте и удаляйте атрибут по мере изменения статуса входа и слушайте события виджета:

const widget = document.querySelector('crow-comments')

// after your site signs the reader in
widget.setAttribute('sso-token', await fetchCrowmentToken())

// after your site signs the reader out
widget.removeAttribute('sso-token')

// the token expired while the page was open: hand over a fresh one
widget.addEventListener('crow:sso-expired', async () => {
  widget.setAttribute('sso-token', await fetchCrowmentToken())
})

// Required mode without a sign-in page: show your own login
widget.addEventListener('crow:login-required', () => openLoginDialog())
  • crow:sso-expired: виджету нужно было авторизовать читателя, но срок токена истёк. Передайте новый.
  • crow:login-required: режим Required, страница входа не задана, и читатель нажал кнопку входа.

Читатели, вошедшие через ваш сайт, выходят тоже на вашем сайте. Если страница выхода не задана, виджет скрывает собственную кнопку выхода, ведь отсутствие токена на следующей странице и так завершит сессию.

4. Привязка аккаунтов

Читатель, у которого уже есть аккаунт Crowment, может привязать его в блоке комментариев с помощью значка ссылки рядом с аватаром. Он входит в Crowment во всплывающем окне и подтверждает действие на странице Crowment. После этого ваш сайт авторизует его под аккаунтом Crowment, а комментарии, написанные с аккаунтом вашего сайта, переходят к этому аккаунту.

Привязка позволяет вашему сайту авторизовать этого читателя под аккаунтом Crowment только на ваших страницах; страница подтверждения сообщает ему об этом. Отвязать аккаунт можно в любой момент в User Console в разделе Profile → Linked sites; комментарии остаются у читателя. Отключить привязку можно параметром Account linking в настройках SSO.

Имя и аватар из вашего токена обновляют профиль читателя в комментариях при каждом входе. Привязанные аккаунты Crowment сохраняют собственные имя и аватар.

Безопасность

  • Храните секрет на сервере. Тот, у кого он есть, может авторизовать на вашем сайте кого угодно под любым именем.
  • При утечке нажмите Replace secret. Токены, подписанные старым секретом, сразу перестают работать, поэтому немедленно разверните новый. Читатели, уже вошедшие в комментарии, остаются авторизованными.
  • Подписывайте токены только для читателя текущего запроса и делайте их короткоживущими.

Устранение неполадок

СимптомВероятная причина
invalid_sso_tokenНеверный или заменённый секрет, aud не совпадает с app key, алгоритм отличен от HS256, sub передан числом, пустое name или срок жизни больше часа.
sso_token_expiredВремя exp токена прошло или часы сервера сбиты. Подписывайте новый токен при каждом просмотре страницы.
SSO is not enabled for this appРежим Off или секрет не создан.
Request origin does not matchСтраница находится не на домене виджета и не на его поддомене.