Сайт или приложение
Человек входит на стороне АИС «Школа», подтверждает доступ, а приложение получает токен его школы. Пароль пользователя не попадает во внешний сервис.
- Authorization Code + PKCE
- Адреса
/api/v1/school/...
Без лишней теории: выберите сценарий входа, получите токен и сделайте первый запрос. Ниже — рабочие примеры, карта данных школы и ответы на частые вопросы.
От этого зависит только способ получения токена и вид адресов.
Человек входит на стороне АИС «Школа», подтверждает доступ, а приложение получает токен его школы. Пароль пользователя не попадает во внешний сервис.
/api/v1/school/...Планировщик или backend получает токен по реквизитам программы. Школа указывается в адресе, а API проверяет выданные программе права на эту школу.
/api/v1/schools/{id}/...Если сервису достаточно знать, кто вошёл, в какой школе и с какой ролью, подключите единую учётную запись Школа ID — стандартный OpenID Connect.
Для первого теста проще всего использовать серверный токен.
Напишите на director@ais-school.ru и опишите вашу интеграцию.
Передайте client_id и client_secret только с вашего сервера.
Добавьте заголовок Authorization: Bearer ... к запросу.
curl -X POST "https://ais-school.ru/api/v1/auth/token/" \
-H "Content-Type: application/json" \
-d '{
"grant_type": "client_credentials",
"client_id": "ais_...",
"client_secret": "YOUR_CLIENT_SECRET"
}'
curl "https://ais-school.ru/api/v1/schools/10/" \
-H "Authorization: Bearer $TOKEN" \
-H "Accept: application/json"
https://ais-school.ru/api/v1/ — официальный адрес API, 10 — ID школы, а ais_... и секрет выдаются после согласования доступа.
Подходит для кабинета, мобильного приложения или другого сервиса, где человек работает со своей школой.
Создайте случайные state и code_verifier.
Из verifier вычислите SHA-256 в формате Base64URL без = —
получится code_challenge. Сохраните state и verifier
в серверной сессии до возврата пользователя.
https://ais-school.ru/api/v1/auth/authorize/
?client_id=ais_...
&redirect_uri=https%3A%2F%2Fclient.example%2Fcallback
&response_type=code
&scope=school.read
&state=RANDOM_STATE
&code_challenge=CHALLENGE
&code_challenge_method=S256
redirect_uri должен полностью совпадать с адресом,
согласованным при подключении. После входа АИС «Школа» вернёт браузер
на этот адрес с параметрами code и state.
Если state не совпал со значением из сессии, остановите вход. Одноразовый code действует 5 минут и используется только один раз.
curl -X POST "https://ais-school.ru/api/v1/auth/token/" \
-H "Content-Type: application/json" \
-d '{
"grant_type": "authorization_code",
"client_id": "ais_...",
"redirect_uri": "https://client.example/callback",
"code": "ONE_TIME_CODE",
"code_verifier": "ORIGINAL_RANDOM_VERIFIER"
}'
Передавать username и password в /auth/token/ нельзя. Для пользовательского входа всегда используйте страницу авторизации.
Client Credentials работает без пользователя и только в границах грантов программы.
/api/v1/auth/me/Проверить программу, пользователя и срок токена
/api/v1/auth/profile/Получить профиль пользователя; для серверного токена вернётся 404
/api/v1/auth/revoke/Немедленно отозвать текущий токен
Не помещайте client_secret в браузерный JavaScript, мобильное приложение, публичный репозиторий или логи.
В пользовательском сценарии школа определяется по профилю. В серверном — указывается явно.
| Операция | OAuth пользователя | Серверный токен |
|---|---|---|
| Карточка школы | /school/ | /schools/{school_id}/ |
| Полный снимок | /school/all/ | /schools/{school_id}/all/ |
| Каталог ресурсов | /school/resources/ | /schools/{school_id}/resources/ |
| Один ресурс | /school/resources/{resource}/ | /schools/{school_id}/resources/{resource}/ |
Реквизиты, адреса, контакты, лицензия, аккредитация, тариф и текущий учебный год.
Школа и весь связанный граф данных. Удобен для первого импорта, но ответ может быть большим.
Отдельные списки с фильтрами — лучший вариант для регулярной синхронизации.
Название справа — значение {resource} в адресе запроса.
academicyearsubjectsgroupsbuildingroomtypesmarkperiodschemeperiodschemeitemperioduserstudentsparentlinkagentworkloadcallscheduletemplatecallscheduleentryscheduletemplatescheduletemplateinfoscheduletypemarkmarkstotalmarksyearfinalmarkktptemplatektptemplateitemktptemplategroupcurriculumplancurriculumitemdebtretakeattendancehomeworkhomeworktargethomeworkattachmentschooldocumentsupportticketsupportmessagesupportattachmentstudentimportjoblogskugschedulestaymodeliterequestslitereportselectionpaymentНичего не найдено. Попробуйте название по-русски или имя ресурса из API.
Запросите GET /api/v1/school/resources/, чтобы увидеть ресурсы, доступные в установленной версии АИС «Школа».
Подставьте имя ресурса и, для одной записи, её ID.
/resources/{resource}/Возвращает count, применённые filters и массив results.
/resources/{resource}/{id}/Возвращает объект или 404, если запись не принадлежит школе.
/resources/{resource}/Требует can_write. Поле школы сервер подставляет сам.
/resources/{resource}/{id}/Передавайте только поля, которые действительно меняются.
/resources/{resource}/{id}/Требует can_write; учитывайте зависимые записи.
id, не как вложенный объект.id при создании не передаётся — его назначит сервер.created_at, updated_at и похожие служебные даты обычно только читаются.PATCH нельзя перенести запись в другую школу.multipart/form-data; JSON-строка не загружает файл.curl -X POST "https://ais-school.ru/api/v1/school/resources/subjects/" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Информатика", "year": 12}'
Фильтры добавляются в строку запроса и всегда ограничиваются текущей школой.
?group=5Точное совпадение?id__in=1,2,3Одно из значений, максимум 500?schedule__period=3Один переход по внешней связи?room=nullПустое значение поляcurl "https://ais-school.ru/api/v1/school/resources/schedule/?group=5&subject=4&period=3" \
-H "Authorization: Bearer $TOKEN"
Неизвестный или небезопасный фильтр возвращает 400 — API не отдаст весь список из-за опечатки. JSON-поля, длинные цепочки связей и скрытые поля пользователя фильтровать нельзя.
Успешные чтение и изменение возвращают 200, создание — 201, удаление и отзыв токена — 204.
API объясняет причину в JSON: {"detail": "Программе не выдано требуемое право для этой школы."}
Не отправляйте client secret и токены в браузер, URL, аналитику или логи.
Для чтения достаточно can_read; запись включайте только когда она действительно нужна.
При OAuth-входе сравнивайте state до обмена одноразового кода на токен.
Вызовите POST /auth/revoke/ и напишите на director@ais-school.ru, чтобы отключить доступ.
Для регулярной синхронизации используйте ресурсы и фильтры, а не частый полный снимок /all/.
Школа ID (id.ais-school.ru) — одна учётная запись человека для всех сервисов
экосистемы. Подключите её, если вашему сервису нужно узнать, кто вошёл, в каких школах и
в каких ролях он работает или учится. Данные школы по-прежнему читаются через API выше.
Протокол — OpenID Connect, поток Authorization Code. PKCE с S256 обязателен
для всех приложений. client_id, секрет и адреса возврата выдаёт администратор
экосистемы — напишите на director@ais-school.ru.
Все адреса и ключи публикуются в discovery-документе.
/.well-known/openid-configurationDiscovery: адреса, scope и алгоритмы
/oauth/authorizeСтраница входа и согласия
/oauth/tokenОбмен кода на токен и id_token
/oauth/userinfoПрофиль по токену доступа
/oauth/revokeОтозвать токен доступа
/oauth/jwksПубличные ключи подписи id_token (RS256)
| Scope | Что получит сервис |
|---|---|
openid | sub — постоянный идентификатор учётной записи и подписанный id_token. Обязателен. |
profile | name, family_name, given_name, middle_name |
email | email и email_verified — почта всегда подтверждена кодом |
organizations | Профили из АИС «Школа», привязанные к учётной записи: школа и роли |
Сохраните в серверной сессии случайные state, nonce и
code_verifier; code_challenge — SHA-256 от verifier в Base64URL
без =. Приложения экосистемы входят без экрана согласия, сторонние —
после того как человек один раз разрешит передачу данных.
https://id.ais-school.ru/oauth/authorize
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https%3A%2F%2Fclient.example%2Fschoolid-callback
&scope=openid%20profile%20email%20organizations
&state=RANDOM_STATE
&nonce=RANDOM_NONCE
&code_challenge=CHALLENGE
&code_challenge_method=S256
Необязательный prompt: none — без показа страниц (если человек не вошёл,
вернётся error=login_required), login — попросить войти заново,
consent — снова показать согласие. В ответ на адрес возврата придут
code, state и iss; при отказе —
error=access_denied.
Тело — форма application/x-www-form-urlencoded. Секрет передайте в теле
или заголовком Authorization: Basic; приложение без секрета отправляет только
client_id и code_verifier. Код живёт 5 минут и одноразовый.
curl -X POST "https://id.ais-school.ru/oauth/token" \
-d grant_type=authorization_code \
-d client_id=YOUR_CLIENT_ID \
-d client_secret=YOUR_CLIENT_SECRET \
-d redirect_uri=https://client.example/schoolid-callback \
-d code=ONE_TIME_CODE \
-d code_verifier=ORIGINAL_RANDOM_VERIFIER
{
"access_token": "…",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "email openid organizations profile",
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ii4uLiJ9…"
}
curl "https://id.ais-school.ru/oauth/userinfo" \
-H "Authorization: Bearer $ACCESS_TOKEN"
{
"sub": "3f2b9c0e5a6d4e1f8b7a9c2d1e0f4a6b",
"name": "Иванова Анна Сергеевна",
"family_name": "Иванова",
"given_name": "Анна",
"middle_name": "Сергеевна",
"email": "anna@example.ru",
"email_verified": true,
"organizations": [
{
"system": "ais",
"system_title": "АИС «Школа»",
"account_id": "1534",
"org_id": "12",
"org_name": "МАОУ «Гимназия №1»",
"roles": ["teacher", "zavuch"]
}
]
}
Сопоставляйте людей по sub: почту и ФИО человек может сменить.
Роли в organizations — director, zavuch,
teacher, student, parent; список может пополняться,
незнакомую роль просто пропускайте. Одна учётная запись может состоять в нескольких
школах и с разными ролями. org_id — номер школы в API АИС «Школа»,
account_id — номер профиля человека в ней.
Подпись — RS256, ключ берите из /oauth/jwks по kid из заголовка.
Сверьте iss = https://id.ais-school.ru, aud = ваш
client_id, срок exp и nonce из сессии.
Организации в id_token не входят — их отдаёт только userinfo.
Повторное предъявление уже использованного кода считается перехватом: выданный по нему токен отзывается. Токен доступа живёт час, refresh-токенов нет — по истечении снова отправьте человека на /oauth/authorize, при открытой сессии Школа ID это пройдёт без ввода пароля.
Полная схема полей каждого ресурса, отзывы и дополнительные оговорки собраны в Markdown-спецификации.