Войти через Shalter
Документация для разработчиков
Открыть Shalter

Войти через Shalter

Небольшой OAuth-поток authorization-code — тот же смысл, что у «Войти через VK» или «Sign in with Google»: человек подтверждает вход в один клик, а ваш сайт получает его открытый профиль (id, имя, юзернейм, аватар) и ничего больше.

Все методы

Управление приложением (нужна сессия Shalter)
GET /api/oauth/appsсписок ваших приложений
POST /api/oauth/appsзарегистрировать приложение
POST /api/oauth/apps/:id/regenerateперевыпустить секрет
DELETE /api/oauth/apps/:idудалить приложение
Поток входа
GET /oauth/authorizeстраница согласия (открывает браузер человека)
POST /api/oauth/tokenкод → access_token (сервер-сервер)
GET /api/oauth/userinfoпрофиль по токену

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

Три действующих лица: человек (в браузере), ваш сайт (браузер + свой сервер) и Shalter.

  1. Человек нажимает «Войти через Shalter» на вашем сайте — браузер уходит на /oauth/authorize.
  2. Shalter показывает свою страницу согласия. Человек подтверждает — браузер возвращается на ваш redirect_uri с одноразовым кодом.
  3. Ваш сервер (не браузер) меняет код на access_token, назвав секрет приложения — секрет никогда не должен попадать в код браузера.
  4. Токеном сервер запрашивает /userinfo и узнаёт, кто вошёл.
Намеренно минимально: один тип гранта (authorization code), без refresh-токенов и без scope — приложение получает ровно одно: открытый профиль. Ничего личного (телефон, переписку, звёзды) через этот вход получить нельзя.

Регистрация приложения

Настройки → Войти через Shalter → «Создать приложение». Укажите имя и redirect_uri — адрес на вашем сайте, куда Shalter вернёт человека после входа (https://, для разработки можно http://localhost).

В ответ приложение получает пару ключей:

ПолеГде используется
client_idпубличный — идёт прямо в ссылку входа, виден всем
client_secretсекретный — только на вашем сервере, для POST /token
client_secret показывается один раз — при создании (и при перевыпуске). Shalter не хранит его в виде, который можно посмотреть повторно. Потеряли — перевыпустите (см. ниже): client_id и redirect_uri при этом не меняются, ссылка входа останется рабочей.

Быстрый старт

Ссылка входа на вашей странице:

https://ваш-сайт.example/login?redirect=/account
<a href="https://shalter.ru/oauth/authorize?client_id=ВАШ_CLIENT_ID&redirect_uri=https://ваш-сайт.example/callback&state=xyz">
  Войти через Shalter
</a>

На вашем сервере, в обработчике /callback:

const CLIENT_ID = process.env.SHALTER_CLIENT_ID;
const CLIENT_SECRET = process.env.SHALTER_CLIENT_SECRET;
const API = "https://shalter.ru/api/oauth";

app.get("/callback", async (req, res) => {
  const { code } = req.query;

  const tokenRes = await fetch(`${API}/token`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      client_id: CLIENT_ID,
      client_secret: CLIENT_SECRET,
      code,
      redirect_uri: "https://ваш-сайт.example/callback",
    }),
  });
  const { access_token, user } = await tokenRes.json();

  // user уже пришёл вместе с токеном — второй запрос за профилем не обязателен.
  // Дальше — заводите свою сессию для user.id, как для любого другого входа.
  req.session.userId = user.id;
  res.redirect("/account");
});

Шаг 1 — /oauth/authorize

Обычная страница, не JSON-эндпоинт — открывается прямо в браузере человека.

ПараметрОписание
client_idобязателен
redirect_uriобязателен, должен буква-в-букву совпадать с зарегистрированным
stateнеобязателен — вернётся в query нетронутым, для защиты от CSRF/сверки сессии

После подтверждения браузер уходит на:

https://ваш-сайт.example/callback?code=...&state=xyz

Шаг 2 — POST /api/oauth/token

Только сервер-сервер — секрет сюда, в браузер никогда.

curl -X POST https://shalter.ru/api/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "...",
    "client_secret": "...",
    "code": "...",
    "redirect_uri": "https://ваш-сайт.example/callback"
  }'

Ответ:

{
  "access_token": "...",
  "token_type": "bearer",
  "user": { "id": "u_...", "name": "Аня", "username": "anna_k", "avatarImage": "..." }
}

Код одноразовый и живёт 5 минут — используйте сразу после редиректа.

Шаг 3 — GET /api/oauth/userinfo

Проверить токен ещё раз (например, при следующем визите, без нового входа) — та же форма профиля:

curl https://shalter.ru/api/oauth/userinfo \
  -H "Authorization: Bearer ВАШ_ACCESS_TOKEN"
{ "id": "u_...", "name": "Аня", "username": "anna_k", "avatarImage": "..." }

Смотреть / удалить

Настройки → «Войти через Shalter» показывает список ваших приложений (имя, client_id, redirect_uri) — client_secret там не появляется повторно, см. выше. Удаление приложения сразу отзывает все выданные им токены — те, кто входил через него, будут отключены при следующей проверке.

Перевыпуск секрета

Кнопка с ключом рядом с приложением. Выдаёт новый client_secret (показывается один раз, как при создании) и сразу делает старый недействительным — обновите его на своём сервере, иначе обмен кода на токен начнёт отвечать invalid_client. client_id и redirect_uri не меняются, ссылка входа остаётся рабочей.

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

  • client_secret — только на вашем сервере. Утёк — сразу перевыпускайте.
  • redirect_uri сверяется буква-в-букву на каждом шаге — заранее зарегистрируйте точный адрес.
  • Проверяйте state на своей стороне, если полагаетесь на него для защиты от CSRF.
  • Токен даёт доступ только к /userinfo — им нельзя читать чаты, отправлять сообщения или менять профиль.

Ошибки

ОтветПричина
401 invalid_clientclient_id/client_secret не совпадают — секрет мог быть перевыпущен
400 invalid_grantкод уже использован, истёк (5 минут) или выдан для другого redirect_uri
401 invalid_tokenaccess_token неверен или приложение, выдавшее его, удалено
404 на /oauth/authorizeclient_id не найден или redirect_uri не совпадает с зарегистрированным

Объекты

User (публичный профиль)

ПолеТипОписание
idстрокаИдентификатор аккаунта Shalter — используйте как внешний ключ у себя.
nameстрокаИмя.
usernameстрока или nullЮзернейм без @, если задан.
avatarImageстрока или nullГотовая ссылка на аватар (или data:-URL).

Адрес API на этом развёртывании — /api/oauth от корня сайта. Управление приложениями — в Shalter, Настройки → «Войти через Shalter».