Разработка LMS-платформы с поддержкой LTI-интеграций

Поддержка LTI-интеграций в LMS

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Разработка LMS-платформы с поддержкой LTI-интеграций
Сложный
от 2 недель до 3 месяцев

Наши компетенции:

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1422
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1288
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    984
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1250
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    986
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    1001

Поддержка LTI-интеграций в LMS

LTI (Learning Tools Interoperability) — стандарт IMS Global для встраивания внешних образовательных инструментов в LMS. Через LTI преподаватель настраивает один раз подключение к Kahoot, Phet Simulations, Coursera for Campus, Microsoft Teams — и студенты запускают их прямо из LMS без отдельной регистрации. Однако на практике LTI-интеграция часто превращается в головную боль: ошибки конфигурации, несовместимость версий (1.1 vs 1.3), потеря сессии при OIDC flow, проблемы с передачей оценок через Outcomes. Неправильная настройка JWKS может привести к тому, что инструмент не примет JWT — и вся интеграция перестаёт работать. Наши инженеры с 10-летним опытом в EdTech решают эти проблемы под ключ — от аудита текущей LMS до подключения любого LTI-инструмента. За годы работы мы накопили библиотеку типовых ошибок и готовых шаблонов, что сокращает время разработки на 30-50%. Мы гарантируем совместимость с любым LTI-совместимым инструментом, сертифицированным IMS Global.

Согласно спецификации IMS Global LTI 1.3, использование OAuth 2.0 и JWKS обеспечивает более высокий уровень безопасности по сравнению с LTI 1.1.

Почему LTI 1.3 лучше LTI 1.1?

LTI 1.1 использует OAuth 1.0 — устаревший протокол с хрупкими подписями. LTI 1.3 базируется на OAuth 2.0 и OpenID Connect: безопаснее, прозрачнее и проще в отладке. JWT-токены с JWKS-ключами исключают подделку запросов. Многие поставщики (Coursera, Zoom, Adobe) переходят на LTI 1.3 — без него вы не сможете подключить современные инструменты.

Характеристика LTI 1.1 LTI 1.3
Протокол OAuth 1.0 OAuth 2.0 + OIDC
Подпись HMAC-SHA1 RSA/JWT
Управление ключами Shared secret (статика) JWKS (ротация)
Безопасность Низкая Высокая
Время на интеграцию 2-3 дня 3-5 дней

Как настроить LTI 1.3 в вашей LMS?

LMS выступает в роли Platform (по IMS). Процесс инициализации включает OIDC Login Request и генерацию JWT. Ниже — типовой код с библиотекой ltijs:

import { Provider } from 'ltijs'; // npm install ltijs // Настройка LMS как LTI Platform Provider.setup( process.env.LTI_ENCRYPTION_KEY!, // 32+ символов для шифрования cookies { url: process.env.DATABASE_URL!, plugin: require('ltijs-postgresql'), // адаптер для PostgreSQL }, { cookies: { secure: true, sameSite: 'None' }, devMode: process.env.NODE_ENV !== 'production', } ); // Регистрация внешнего инструмента await Provider.registerPlatform({ url: 'https://tool.example.com', name: 'Kahoot Integration', clientId: process.env.KAHOOT_CLIENT_ID!, authenticationEndpoint: 'https://tool.example.com/lti/auth', accesstokenEndpoint: 'https://tool.example.com/lti/token', authConfig: { method: 'JWK_SET', key: 'https://tool.example.com/.well-known/jwks.json', }, }); // Обработчик запуска инструмента Provider.onConnect(async (token, req, res) => { const { email, name, role } = token.userInfo; const contextId = token.platformContext.context?.id; // Проверить/создать пользователя во внешнем инструменте res.json({ token: token.jwt }); }); await Provider.deploy({ serverless: true }); 

LTI 1.1 — для устаревших инструментов

Часть поставщиков (Phet, некоторые тесты) всё ещё использует LTI 1.1 с OAuth 1.0 подписью:

import oauth from 'oauth-signature'; function launchLti11( launchUrl: string, consumerKey: string, consumerSecret: string, params: Record<string, string> ): { url: string; method: 'POST'; body: string } { const baseParams: Record<string, string> = { lti_message_type: 'basic-lti-launch-request', lti_version: 'LTI-1p0', oauth_callback: 'about:blank', oauth_consumer_key: consumerKey, oauth_nonce: crypto.randomUUID().replace(/-/g, ''), oauth_signature_method: 'HMAC-SHA1', oauth_timestamp: String(Math.floor(Date.now() / 1000)), oauth_version: '1.0', ...params, }; const signature = oauth.generate('POST', launchUrl, baseParams, consumerSecret, ''); baseParams.oauth_signature = signature; const body = new URLSearchParams(baseParams).toString(); return { url: launchUrl, method: 'POST', body }; } // Страница запуска LTI инструмента app.get('/courses/:courseId/tools/:toolId/launch', authenticate, async (req, res) => { const tool = await db.ltiTools.findById(req.params.toolId); const enrollment = await db.enrollments.findByCourseAndUser( req.params.courseId, req.user.id ); if (tool.version === '1.1') { const launch = launchLti11(tool.launch_url, tool.consumer_key, tool.consumer_secret, { resource_link_id: `${req.params.courseId}-${req.params.toolId}`, resource_link_title: tool.name, user_id: req.user.id, lis_person_name_full: req.user.name, lis_person_contact_email_primary: req.user.email, roles: enrollment.role === 'instructor' ? 'Instructor' : 'Student', context_id: req.params.courseId, context_title: enrollment.courseTitle, }); // Авто-сабмит форму через HTML res.send(` <!DOCTYPE html> <html> <body> <form id="lti" method="POST" action="${launch.url}"> ${Object.entries(Object.fromEntries(new URLSearchParams(launch.body))) .map(([k, v]) => `<input type="hidden" name="${k}" value="${v}" />`) .join('\n')} </form> <script>document.getElementById('lti').submit();</script> </body> </html> `); } }); 

Хранение конфигурации инструментов

CREATE TABLE lti_tools ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), course_id UUID REFERENCES courses(id), name VARCHAR(255) NOT NULL, version VARCHAR(10) NOT NULL, -- '1.1' | '1.3' -- LTI 1.1 launch_url TEXT, consumer_key VARCHAR(255), consumer_secret TEXT, -- LTI 1.3 client_id VARCHAR(255), platform_id VARCHAR(255), deployment_id VARCHAR(255), oidc_auth_url TEXT, jwks_url TEXT, -- Настройки open_in_new_tab BOOLEAN DEFAULT false, custom_params JSONB DEFAULT '{}', created_at TIMESTAMPTZ DEFAULT now() ); 

Получение результатов через LTI Outcomes (1.1)

// Инструмент может отправить оценку обратно в LMS app.post('/lti/grade', async (req, res) => { const { sourcedId, score, action } = parseLtiOutcomesXml(req.body); // sourcedId содержит userId и resourceLinkId const [userId, resourceId] = parseLisResultSourcedId(sourcedId); await db.ltiGrades.upsert({ userId, resourceId, score: Number(score), receivedAt: new Date(), }); // Обновить прогресс курса await updateCourseProgress(userId, resourceId, Number(score)); res.type('application/xml').send(` <?xml version="1.0" encoding="UTF-8"?> <imsx_POXEnvelopeResponse xmlns="http://www.imsglobal.org/services/ltiv1p1/xsd/imsoms_v1p0"> <imsx_POXHeader> <imsx_POXResponseHeaderInfo> <imsx_version>V1.0</imsx_version> <imsx_messageIdentifier>${crypto.randomUUID()}</imsx_messageIdentifier> <imsx_statusInfo> <imsx_codeMajor>success</imsx_codeMajor> <imsx_severity>status</imsx_severity> </imsx_statusInfo> </imsx_POXResponseHeaderInfo> </imsx_POXHeader> <imsx_POXBody><replaceResultResponse /></imsx_POXBody> </imsx_POXEnvelopeResponse> `); }); 

Что входит в работу по LTI-интеграции?

  • Аудит текущей архитектуры LMS: выявление узких мест (N+1 запросы, потери сессий), оценка совместимости с нужными инструментами.
  • Проектирование схемы хранения конфигураций инструментов (таблица lti_tools с поддержкой обеих версий LTI).
  • Реализация LTI 1.1 и/или LTI 1.3 launch flow на вашем стеке (Node.js, Python, PHP, Ruby — любой).
  • Интеграция с внешним инструментом: регистрация, тестовый запуск, передача оценок (Outcomes).
  • Написание документации для администраторов и инструкторов по добавлению новых инструментов.
  • Обучение команды: как отлаживать ошибки, обновлять ключи, работать с JWKS.
  • Пост-релизная поддержка в течение 30 дней: исправление багов, консультации.
Часто встречающиеся ошибки при LTI-интеграции
  • Несоответствие типов пользователей: путают роль Instructor и Student в JWT.
  • Ошибки JWKS: ключи истекают или не обновляются.
  • Проблемы с CORS: внешние инструменты блокируют запросы.
  • Неправильная настройка OIDC Login Request: неверный redirect URI.

Сроки и стоимость

LTI 1.1 интеграция (Consumer + Launch + Grades) — 3–5 дней. LTI 1.3 с OIDC flow — 1 неделя. Поддержка обеих версий + UI управления инструментами — 2 недели. Стоимость рассчитывается индивидуально, а использование готовых шаблонов позволяет существенно сократить бюджет.

Наш опыт и гарантии

Кейс: интеграция Kahoot в LMS университета. Потребовалась поддержка LTI 1.3, так как Kahoot перешёл на новый стандарт. Мы реализовали OIDC flow, настроили JWKS и протестировали передачу оценок. В результате студенты получили единый интерфейс без повторной аутентификации. Получите консультацию по интеграции LTI уже сегодня. Свяжитесь с нами — оценим вашу задачу и предложим решение в течение 2 рабочих дней. Обращайтесь, чтобы повысить удобство вашей LMS.