Аутентификация: ключи API и OAuth
Обновлено 27.10.2026
В API ВИШ три способа обратиться к методу: без входа, с ключом API и с токеном OAuth от «Входа через ВИШ». Какой выбрать — зависит от того, чьи данные вы читаете и кто запускает программу. Сверено со стендом d1 23 октября 2026 года.
Что выбрать
| Без входа | Ключ API | Токен OAuth («Вход через ВИШ») | |
|---|---|---|---|
| Для чего | Открытые данные: расписание, группы, преподаватели, аудитории | Ваш скрипт, бот, выгрузка, дашборд | Ваш сайт или приложение, куда входят другие люди |
| От чьего имени | Ничьего | От вашего, в пределах прав ключа | От имени вошедшего человека, с его согласия |
| Как передаётся | — | Заголовок X-Api-Key: vish_… | Заголовок Authorization: Bearer … |
| Что можно | Открытые методы GET | Всё, что разрешено ключу и вашей роли | Только чтение из короткого списка методов |
| Срок | — | До даты в ключе (выпущенный себе — не дольше 730 дней) | 15 минут, дальше обновление токеном refresh |
| Где есть | d1 и production | d1 и production | Пока только d1 |
Если ничего личного читать не нужно — обходитесь без входа: меньше секретов, меньше рисков.
Ключ API
Ключ получают на странице «Для разработчиков» в приложении — подробно на странице API и ключи доступа. Ключ начинается с vish_ и передаётся в отдельном заголовке:
curl -H "X-Api-Key: $VISH_API_KEY" "$VISH_API/auth/me"
- Запрос с ключом — это запрос от вашего имени, но только в пределах прав, отмеченных при выпуске ключа. Чего нет в наборе, тому ключ получит отказ, даже если у вас самих это право есть. Если права вашей роли потом уменьшились, ключ тоже теряет их — сразу, со следующего запроса.
- Ключ — в заголовке, никогда в адресе: адреса оседают в журналах, истории браузера и заголовке
Referer. - Если в запросе и ключ, и
Authorization, засчитывается ключ. - Некоторые методы только для человека в приложении: свой ключ, личные заметки, согласия, удаление аккаунта. Ключом их не вызвать — ответ 403
SESSION_REQUIRED. - Ключ, который где-то засветился, перевыпустите кнопкой «Перевыпустить» на странице «Для разработчиков»: старая строка перестаёт работать сразу.
Проверить ключ и посмотреть, что ему разрешено:
// Who the key acts as, and which permissions it carries.
const API = process.env.VISH_API ?? 'https://d1.vish-app.ru/api/v1'
const KEY = process.env.VISH_API_KEY
if (!KEY) throw new Error('set VISH_API_KEY')
const response = await fetch(`${API}/auth/me`, { headers: { 'X-Api-Key': KEY } })
const me = await response.json()
if (!response.ok || !me.id) throw new Error(`HTTP ${response.status}: ${JSON.stringify(me)}`)
console.log('role:', me.role)
console.log('permissions:', me.permissions.length ? me.permissions.join(', ') : '(none: public reads only)')Токен OAuth
Токен доступа выдаёт «Вход через ВИШ»: человек входит в ваше приложение аккаунтом ВИШ и разрешает ему доступ. Как это подключить — на странице Вход через ВИШ для разработчиков. Здесь — чем токен отличается от ключа:
- Передаётся в заголовке
Authorization: Bearer <access_token>. - Действует от имени вошедшего человека, но только на чтение и только для методов, которые называет выданное разрешение:
schedule:read—GET /schedule,GET /schedule/subscriptions/mine,GET /schedule/{id}/subscription;notes:read—GET /schedule/{id}/notes. Любой другой метод ответит 403OAUTH_SCOPE_INSUFFICIENT. - Права сотрудника или администратора, если они есть у человека, токену не передаются.
- Живёт 15 минут; новый получают токеном refresh (30 дней, меняется при каждом обновлении).
- Со страницы другого сайта браузер не даст прочитать ответы на такие запросы (CORS): методы расписания с токеном зовите со своего сервера. Из браузера доступны только протокольные адреса
/oauth/…. - Человек может отключить ваше приложение в «Настройки» → «Доступ» → «Подключённые приложения» — токены перестают работать со следующего запроса.
Вход в само приложение
Приложение ВИШ входит через Telegram или MAX и получает свой Bearer-токен. Этот вход — для людей в приложении, а не для интеграций: не пытайтесь повторить его из скрипта. Скрипту — ключ, чужому сайту — «Вход через ВИШ».
Ошибки входа
| HTTP | error.code | Что случилось |
|---|---|---|
| 401 | AUTH_REQUIRED | Метод требует входа, а ни ключа, ни токена нет |
| 401 | UNAUTHORIZED | Ключ неверный, отозван, просрочен или его владельца больше нет |
| 401 | ACCESS_TOKEN_INVALID | Bearer-токен неверный или истёк — обновите его |
| 403 | SESSION_REQUIRED | Метод только для человека в приложении |
| 403 | OAUTH_SCOPE_INSUFFICIENT | Токену OAuth этот метод не разрешён |
| 403 | FORBIDDEN | Не хватает прав — см. Права доступа (RBAC) |
Как выглядят отказы — без настоящего ключа, на заведомо неверных значениях:
// A made-up key and a made-up bearer token are both refused with 401.
const API = process.env.VISH_API ?? 'https://d1.vish-app.ru/api/v1'
const attempt = async (headers) => {
const response = await fetch(`${API}/auth/me`, { headers })
return { status: response.status, code: (await response.json()).error?.code }
}
const key = await attempt({ 'X-Api-Key': 'vish_not_a_real_key' })
const bearer = await attempt({ Authorization: 'Bearer not-a-real-token' })
if (key.status !== 401 || key.code !== 'UNAUTHORIZED') throw new Error(`key: ${JSON.stringify(key)}`)
if (bearer.status !== 401 || bearer.code !== 'ACCESS_TOKEN_INVALID') throw new Error(`bearer: ${JSON.stringify(bearer)}`)
console.log('made-up key ->', key.status, key.code)
console.log('made-up token ->', bearer.status, bearer.code)Попробовать: метод ниже без ключа ответит 401, а с вашим ключом в поле «Ключ API» — вашими данными. Ключ остаётся только в этой вкладке и никуда не сохраняется.
Попробовать запрос
Ключ нужен только методам с замком. Он живёт только на этой странице: не сохраняется, уходит лишь заголовком этого запроса и забывается, когда вы её покинете. Где взять ключ
Проверено: 2026-10, PWA aa337c45, platform bff65fce.