LTI 1.3 en Moodle: Integración Paso a Paso

LTI 1.3 en Moodle: Integración Paso a Paso

En el ecosistema educativo actual, la interoperabilidad ya no es un lujo, sino una necesidad clave. Las instituciones que utilizan Moodle enfrentan el creciente desafío de integrar herramientas externas —desde sistemas de videoconferencia y simuladores interactivos, hasta plataformas de evaluación y analítica avanzada— de forma seguraestable y fácil de usar tanto para docentes como para estudiantes.

Aquí es donde entra en juego LTI 1.3 (Learning Tools Interoperability), el estándar abierto desarrollado por IMS Global Learning Consortium. Gracias a su amplia adopción y a las mejoras significativas respecto a versiones anteriores como la 1.1, se ha convertido en la puerta de entrada para conectar Moodle con prácticamente cualquier servicio EdTech.

A diferencia de sus predecesores, LTI 1.3 se basa en protocolos modernos como OAuth 2.0 y OpenID Connect, lo que proporciona un marco de seguridad mucho más robusto y flexible para las integraciones educativas del futuro.

🧪 ¿Qué aprenderás en este tutorial?

Realizaremos una integración funcional paso a paso. Lo que haremos será:

  • Configurar Moodle como una plataforma LTI 1.3.
  • Desarrollar un proveedor de herramienta básico en Node.js.
  • Probar el flujo completo de autenticación y lanzamiento.

🎯 Objetivo: Que al finalizar este artículo tengas un ejemplo real y funcional, listo para adaptarse a tu propio caso de uso.


TABLA DE CONTENIDOS

1. Conceptos Básicos de LTI 1.3

Antes de comenzar la implementación técnica, es fundamental comprender cómo funciona LTI 1.3 y los elementos clave que lo componen. Si ya tienes conocimientos sobre OAuth 2.0, muchos de estos conceptos te resultarán familiares.

🔑 Roles Clave

  • 🧭 Plataforma (Platform): Es el sistema central de aprendizaje, en este caso Moodle. Es responsable de gestionar los cursos, usuarios y es desde donde se “lanza” la herramienta externa.
  • 🧩 Proveedor de Herramienta (Tool): Es la aplicación o servicio externo que deseas integrar. Puede ser una herramienta desarrollada internamente, un simulador, una solución de evaluación o cualquier otro recurso EdTech.

🔐 Seguridad y Flujo de Autenticación

LTI 1.3 reemplaza el antiguo modelo basado en consumer_key y shared_secret (utilizado en LTI 1.1) por un modelo moderno, robusto y más seguro fundamentado en OAuth 2.0 y OpenID Connect (OIDC).

  • 🔏 Firmas con JWT y JWKS:
    • Moodle actúa como emisor y firma un id_token con su clave privada.
    • La herramienta valida esa firma utilizando una clave pública que se obtiene desde un endpoint conocido como JWKS (JSON Web Key Set).
  • 🆔 Identificadores únicos implicados en el flujo:
    • client_id: identificador único asignado a la herramienta.
    • deployment_id: ID para cada instancia de uso de la herramienta en Moodle.
    • issuer: identifica la plataforma Moodle que lanza la herramienta.

🚀 El Flujo de Lanzamiento Simplificado

El LTI Launch Flow consta de tres pasos principales que garantizan una autenticación segura y contextualizada:

✅ Puntos Clave de esta Sección

  • LTI 1.3 utiliza tecnologías modernas de autenticación: OAuth 2.0 + OIDC.
  • El flujo de autenticación consta de tres pasos claros: inicio de sesión, redirección y lanzamiento.
  • La seguridad se garantiza mediante el uso de JWT firmados y verificados con claves públicas compartidas a través de JWKS.

2. Preparar Moodle como Plataforma LTI 1.3

Configurar Moodle para que funcione como una plataforma LTI 1.3 es esencial para garantizar una integración exitosa con herramientas externas. Para realizar estos pasos, necesitas acceso como administrador en tu instancia de Moodle.

✅ Paso 1: Activar el Protocolo LTI Advantage

Antes de registrar cualquier herramienta, debes asegurarte de que Moodle tenga habilitado el soporte para LTI 1.3 (también conocido como LTI Advantage):

  1. Ve a Administración del sitio → Extensiones → Gestionar herramientas.
  2. Asegúrate de que el ícono del ojo junto a “LTI” esté abierto (si está tachado, haz clic para activarlo).
  3. Luego accede a Administración del sitio → Extensiones → Herramientas LTI → Opciones de los servicios de interoperabilidad.
  4. Marca la opción Habilitar el protocolo LTI Advantage.

💡 Este paso es crucial: sin él, Moodle no permitirá configuraciones con LTI 1.3.

🔧 Paso 2: Registrar una Herramienta Externa Manualmente

Una vez activado LTI Advantage, el siguiente paso es registrar tu herramienta externa de forma manual.

  1. Ve a Administración del sitio → Extensiones → Gestionar herramientas.
  2. Haz clic en Configurar una herramienta manualmente.
  3. Rellena el formulario con los detalles técnicos de tu herramienta.

Campos clave que debes completar:

CampoDescripción
Nombre de la herramientaUn nombre descriptivo para identificarla fácilmente. Ej: Mi Herramienta de Ejemplo
URL de la herramientaPágina de inicio o punto de entrada principal. Ej: https://mi-servidor-lti.com
Versión de LTISelecciona LTI 1.3 del menú desplegable.
Tipo de clave públicaElige URL del conjunto de claves (JWKS URL).
JWKS URLEj: https://mi-servidor-lti.com/jwks.json
URL de inicio de sesiónEj: https://mi-servidor-lti.com/login
URI(s) de redirecciónEj: https://mi-servidor-lti.com/launch
Parámetros personalizados(opcional)Puedes agregar parámetros como institucion=MiUniversidad.
Uso de la configuraciónMarca Mostrar como herramienta preconfigurada… para facilitar su selección desde los cursos.

📄 Paso 3: Obtener los Detalles de la Plataforma Moodle

Después de guardar la herramienta, Moodle generará varios datos clave que tu aplicación necesitará para completar el flujo LTI:

  1. Ve a Administración del sitio → Extensiones → Gestionar herramientas.
  2. Busca tu herramienta y haz clic en Ver detalles de la configuración.

Copia y guarda los siguientes valores:

  • 🌐 Platform ID: URL base de Moodle (por ejemplo, https://campus.miuniversidad.edu).
  • 🧾 Client ID: Identificador único para tu herramienta.
  • 🧩 Deployment ID: ID único para la instancia de la herramienta en Moodle.
  • 🔑 Public keyset URL (JWKS): Endpoint público para validar los tokens.
  • 🎫 Access token URL: URL para solicitar tokens y consumir servicios (calificaciones, etc.).
  • 🔐 Authentication request URL: URL a la que la herramienta debe redirigir al usuario para autenticación.

3. Implementar el Proveedor de Herramienta (Tool)

Vamos a construir una herramienta LTI básica utilizando Node.js y el framework Express. Esta aplicación actuará como nuestro Tool Provider, y será capaz de recibir lanzamientos desde Moodle.

🧰 Prerrequisitos Técnicos

Antes de comenzar, asegúrate de cumplir con los siguientes requisitos:

  • Tener instalado Node.js y npm en tu sistema.
  • Conocimientos básicos de JavaScript y Express.js.
  • Acceso a una forma de exponer tu servidor local a internet (por ejemplo, usando ngrok).

🛠 Paso 1: Crear la Estructura del Proyecto

  1. Crea un nuevo directorio y navega a él:

Bash

Bash
mkdir moodle-lti-tool
cd moodle-lti-tool
  1. Inicializa un proyecto de Node e instala las dependencias necesarias:

Bash

Bash
npm install express express-session body-parser jsonwebtoken node-jose

¿Para qué sirve cada paquete?

Estos paquetes son los pilares del proveedor de herramienta LTI 1.3. Juntos permiten crear un servidor seguro, receptivo y compatible con el estándar. Aquí te explico el rol de cada uno, con enlaces a su documentación oficial para que puedas explorar más a fondo.

🔹 express – El motor web de tu herramienta

📚 https://expressjs.com

Express.js es un framework web minimalista para Node.js que te permite crear servidores HTTP de forma rápida y sencilla. En esta integración, lo usamos para definir las rutas clave del flujo LTI 1.3:

  • /jwks.json: Para exponer tu clave pública.
  • /login: Punto de inicio del flujo OIDC.
  • /launch: Donde se procesa el lanzamiento desde Moodle.

Es el cimiento sobre el que se construye toda la aplicación. Sin él, no podrías recibir solicitudes ni servir respuestas.

🔹 express-session – Gestión segura de sesiones

📚 https://www.npmjs.com/package/express-session

Este middleware permite almacenar datos temporales del usuario entre solicitudes HTTP, lo cual es esencial para la seguridad del flujo OpenID Connect (OIDC).

En LTI 1.3, usamos express-session para:

  • Guardar el state y el nonce generados antes del inicio de sesión.
  • Validar que el state recibido en el lanzamiento sea el mismo que el enviado, evitando ataques de CSRF (Cross-Site Request Forgery).
  • Mantener el contexto del usuario durante el proceso de autenticación.

⚠️ Importante: En producción, no uses el almacenamiento en memoria. Considera usar Redis o una base de datos para sesiones distribuidas.

🔹 body-parser – Procesamiento de datos en solicitudes

📚 https://www.npmjs.com/package/body-parser

Aunque en versiones recientes de Express se ha integrado parcialmente, body-parser sigue siendo clave para parsear correctamente el cuerpo de las solicitudes POST que Moodle envía durante el lanzamiento LTI.

En este caso, es fundamental para:

  • Leer el id_token que Moodle envía como parámetro en el POST /launch.
  • Acceder a otros datos del formulario, como statelogin_hint, o target_link_uri.

Sin este paquete, req.body estaría vacío y no podrías procesar el token JWT.

🔹 jsonwebtoken – Decodificación y verificación de tokens

📚 https://www.npmjs.com/package/jsonwebtoken

Este paquete permite decodificar y verificar JSON Web Tokens (JWT), que son el corazón del flujo LTI 1.3.

En tu herramienta:

  • Moodle firma un id_token que contiene información del usuario, rol, curso y contexto.
  • Usas jsonwebtoken para decodificarlo y extraer sus datos (payload).
  • En versiones avanzadas, puedes usarlo también para verificar la firma del token contra la clave pública de Moodle (vía JWKS).

💡 Siguiente paso: Combínalo con jwks-rsa o node-jose para una verificación completa del token.

🔹 node-jose – Criptografía y manejo de claves JWKS

📚 https://www.npmjs.com/package/node-jose

Este es el paquete más técnico, pero también el más poderoso. node-jose implementa el estándar JSON Object Signing and Encryption (JOSE), que incluye JWT, JWK, JWKS y JWS.

En tu integración LTI 1.3, lo usas para:

  • Generar un par de claves RSA (pública/privada) con generate-keys.js.
  • Crear un endpoint JWKS (/jwks.json) que exponga tu clave pública a Moodle.
  • Validar tokens firmados por Moodle (en flujos avanzados).
  • Trabajar con formatos criptográficos estándar (JWK, JWKS) que exige el protocolo LTI 1.3.

✅ Tip: El archivo keys.json generado por node-jose es compatible directamente con el estándar, lo que facilita la interoperabilidad.


🧩 ¿Cómo encajan todos estos paquetes?

🔑 Paso 2: Generar Claves (JWKS) para la Herramienta

Tu herramienta necesita su propio par de claves para comunicarse con Moodle de forma segura.

  1. Crea un archivo generate-keys.js con el siguiente contenido:

JavaScript

JavaScript
const jose = require('node-jose');
const fs = require('fs');

async function generate() {
  const keystore = jose.JWK.createKeyStore();
  await keystore.generate('RSA', 2048, { alg: 'RS256', use: 'sig' });
  fs.writeFileSync('keys.json', JSON.stringify(keystore.toJSON(true), null, 2));
  console.log('Claves generadas y guardadas en keys.json');
}

generate();
  1. Ejecuta el script:

Bash

Bash
node generate-keys.js

Esto generará el archivo keys.json con la clave pública y privada de tu herramienta.

🌐 Paso 3: Crear el Servidor Express

En este paso, crearás un servidor Node.js utilizando Express que implementa los endpoints requeridos por la especificación LTI 1.3.

Crea un archivo llamado index.js con el siguiente contenido. Este código define tres rutas clave para el flujo LTI:

/jwks.json: Exposición de la clave pública

Este endpoint devuelve las claves públicas (en formato JWKS) que Moodle utilizará para verificar la firma del id_tokenenviado por la herramienta.

/login: Inicio de sesión OIDC

Este endpoint se encarga de recibir los parámetros del lanzamiento (como issclient_idlogin_hint, etc.), generar un state y nonce únicos, almacenarlos en la sesión del usuario, y redirigir la petición al authorization_endpoint del LMS (en este caso, Moodle).

/launch: Procesamiento del lanzamiento

Este endpoint recibe el id_token enviado por Moodle, verifica su validez y firma, y extrae la información del usuario y el curso. Si todo es correcto, devuelve una vista de confirmación del lanzamiento exitoso.

Este servidor básico es suficiente para permitir el registro dinámico y lanzar actividades LTI desde Moodle. A partir de aquí puedes extenderlo para soportar funcionalidades como Deep Linkingcalificación (AGS) o servicio de nombres y roles (NRPS).

A continuación, te dejo el archivo index.js, que constituye el núcleo de la herramienta LTI desarrollada en Node.js. Este servidor Express implementa los endpoints esenciales para la interoperabilidad con Moodle a través de LTI 1.3: /jwks.json para exponer la clave pública utilizada en la verificación de firmas JWT, /login para iniciar el flujo de autenticación OIDC, y /launch para procesar el lanzamiento de la herramienta. Además, gestiona la sesión del usuario, valida el token de lanzamiento y muestra la información contextual del curso y del usuario una vez que el proceso ha sido verificado con éxito.

JavaScript

JavaScript
require('dotenv').config();
const express = require('express');
const session = require('express-session');
const bodyParser = require('body-parser');
const fs = require('fs');
const jose = require('node-jose');
const jwt = require('jsonwebtoken');
const fetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args));


const app = express();
const PORT = process.env.PORT || 3000;

app.set('trust proxy', 1); // necesario si usas ngrok o HTTPS

// Cargar claves JWKS
const keystore = jose.JWK.createKeyStore();
const keys = JSON.parse(fs.readFileSync('./keys.json'));
keystore.add(keys.keys[0]);

process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; // ignora errores SSL (solo para testing)

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(session({
  secret: process.env.SESSION_SECRET || 'un-secreto-muy-seguro-y-largo-aqui',
  resave: false,
  saveUninitialized: true,
  cookie: {
    secure: true,
    sameSite: 'none'
  }
}));

// Página principal
app.get('/', (req, res) => {
  res.send(`
    <h1>🌐 Servidor LTI 1.3 Activo</h1>
    <ul>
      <li><a href="/.well-known/openid-configuration">Ver configuración OpenID</a></li>
      <li><a href="/jwks.json">Ver claves públicas (JWKS)</a></li>
    </ul>
  `);
});

// Configuración OpenID
app.get('/.well-known/openid-configuration', (req, res) => {
  const baseUrl = process.env.BASE_URL || `https://${req.headers.host}`;
  res.json({
    issuer: baseUrl,
    authorization_endpoint: `${baseUrl}/login`,
    token_endpoint: `${baseUrl}/token`,
    jwks_uri: `${baseUrl}/jwks.json`,
    response_types_supported: ['id_token'],
    subject_types_supported: ['public'],
    id_token_signing_alg_values_supported: ['RS256'],
    scopes_supported: ['openid'],
    claims_supported: ['sub']
  });
});

// JWKS público
app.get('/jwks.json', (req, res) => {
  res.json(keystore.toJSON());
});

// Login OIDC (GET/POST)
app.all('/login', (req, res) => {
  const query = req.method === 'POST' ? req.body : req.query;
  const { iss, login_hint, target_link_uri, client_id, lti_message_hint } = query;

  console.log('📥 Petición a /login con:', query);

  if (!iss || !login_hint || !client_id || !target_link_uri) {
    return res.status(400).send('Faltan parámetros requeridos');
  }

  const state = Math.random().toString(36).substring(2, 15);
  const nonce = Math.random().toString(36).substring(2, 15);

  console.log('🧠 Guardando state en sesión:', state);

  req.session.state = state;
  req.session.nonce = nonce;
  req.session.client_id = client_id;

  const authUrl = new URL(`${iss}/mod/lti/auth.php`);
  const params = new URLSearchParams({
    response_type: 'id_token',
    response_mode: 'form_post',
    scope: 'openid',
    client_id,
    redirect_uri: process.env.REDIRECT_URI || `${process.env.BASE_URL}/launch`,
    login_hint,
    target_link_uri,
    state,
    nonce,
    prompt: 'none'
  });

  if (lti_message_hint) {
    params.append('lti_message_hint', lti_message_hint);
  }

  res.redirect(`${authUrl}?${params.toString()}`);
});

// Lanzamiento
app.post('/launch', async (req, res) => {
  const { id_token, state } = req.body;

  console.log('🧠 State recibido:', state);
  console.log('🧠 State en sesión:', req.session.state);

  if (!id_token) return res.status(400).send('Falta el id_token');
  if (!state || req.session.state !== state) return res.status(400).send('Invalid state');

  try {
    const decoded = jwt.decode(id_token, { complete: true });
    if (!decoded) return res.status(400).send('Token JWT inválido');

    const { payload } = decoded;
    const expectedIssuer = process.env.PLATFORM_ISSUER || 'https://tu-moodle.com';
    const expectedClientId = req.session.client_id;

    console.log(payload);
    if (payload.iss !== expectedIssuer) return res.status(401).send('Issuer no válido');
    if (
      (Array.isArray(payload.aud) && !payload.aud.includes(expectedClientId)) ||
      (!Array.isArray(payload.aud) && payload.aud !== expectedClientId)
    ) {
      return res.status(401).send('Client ID no válido');
    }

    if (payload.nonce !== req.session.nonce) return res.status(401).send('Nonce no válido');

    const jwksUrl = `${payload.iss}/mod/lti/certs.php`;
    const jwks = await fetch(jwksUrl).then(res => res.json());
    const client = await jose.JWK.asKeyStore(jwks);
    await jose.JWS.createVerify(client).verify(id_token);

    res.send(`
      <h1>✅ Lanzamiento Exitoso</h1>
      <p><strong>Usuario:</strong> ${payload.name || payload.email}</p>
      <p><strong>Rol:</strong> ${payload['https://purl.imsglobal.org/spec/lti/claim/roles']}</p>
      <p><strong>Curso:</strong> ${payload['https://purl.imsglobal.org/spec/lti/claim/context']?.title || 'Desconocido'}</p>
      <p><strong>Deployment ID:</strong> ${payload['https://purl.imsglobal.org/spec/lti/claim/deployment_id']}</p>
    `);
  } catch (err) {
    console.error('Error al verificar el token:', err.message);
    res.status(500).send(`<h1>❌ Error al procesar el lanzamiento</h1><p>${err.message}</p>`);
  }
});

// Servidor activo
app.listen(PORT, () => {
  console.log(`✅ Servidor LTI escuchando en http://localhost:${PORT}`);
  console.log(`🔗 JWKS disponible en http://localhost:${PORT}/jwks.json`);
});

💡 Recuerda actualizar los valores como https://tu-url-publica/launch con la URL real que expones a Moodle (por ejemplo, la que te da ngrok).


🛠️ Variables de entorno recomendadas (.env)

Crea un archivo .env con las siguientes variables de entorno.

Bash

INI
PORT=3000
SESSION_SECRET=una_clave_muy_larga_y_segura_para_sesiones
REDIRECT_URI=https://tu-ngrok.ngrok-free.app/launch
BASE_URL=https://tu-ngrok.ngrok-free.app
PLATFORM_ISSUER=https://tu-moodle.com

4. Prueba y Depuración

Con tu servidor Node.js ya en funcionamiento, es hora de validar que todo esté configurado correctamente.

💡 Consejo Pro: Exponer tu Servidor Local con ngrok

Si estás desarrollando en tu máquina local, necesitarás hacer tu servidor accesible desde internet. ngrok es una herramienta ideal para esto.

Pasos para usar ngrok:
  1. Descarga e instala ngrok desde su sitio oficial:https://ngrok.com/
  2. Inicia tu servidor con: node index.js
  3. En una nueva terminal, ejecuta: ngrok http 3000
  1. ngrok te proporcionará una URL pública (por ejemplo, https://abcd1234.ngrok-free.app).
  2. Actualiza las URLs de tu herramienta en Moodle con esta nueva URL:
    • URL de inicio de sesión
    • JWKS URL
    • URI de redirección

⚙️ Añadir la Aplicación Externa en Moodle

Antes de poder utilizar tu herramienta LTI en un curso, primero debes registrarla como herramienta externa LTI 1.3 en Moodle. Sigue estos pasos:

  1. Inicia sesión en Moodle como administrador.
  2. Ve a Administración del sitio → Plugins → Módulos de actividad → Herramienta externa → Herramientas gestionadas.
Moodle, página de configuración de herramientas externas LTI
Moodle, página de configuración de herramientas externas LTI

🛠️ Configurar una Herramienta LTI Externa Manualmente en Moodle

Desde el panel de administración de Moodle, ve a:

Administración del sitio → Extensiones → Herramientas externas → Administrar herramientas externas
Haz clic en “Añadir una herramienta” y completa el formulario como sigue:

CampoValor a ingresar
Nombre de la herramientaMi herramienta LTI Externa (elige un nombre descriptivo)
URL de la herramientahttps://abcd1234.ngrok-free.app (la raíz de tu servidor LTI)
Versión LTILTI 1.3
Tipo de clave públicaURL del conjunto de claves
Conjunto de claves públicashttps://abcd1234.ngrok-free.app/jwks.json
Iniciar URL de inicio de sesiónhttps://abcd1234.ngrok-free.app/login
URI(s) de redirecciónhttps://abcd1234.ngrok-free.app/launch
Parámetros personalizados(vacío, opcional)
Mostrar como herramienta preconfigurada✅ Activado
Contenedor de inicio por defectoIncrustar, sin bloques
Admite enlaces profundos✅ Activado
URL de selección de contenido(vacío, opcional, se usa solo para deep linking)
Compartir el nombre del usuario con la herramientaSiempre ( si quieres poder recuperar el nombre del usuario )
Compartir el e-mail del usuario con la herramientaSiempre ( si quieres poder recuperar el email del usuario )

Finalmente, pulsa Guardar cambios.

Moodle, página de configuración de herramienta externa LTI 1.3 manualmente
Moodle, página de configuración de herramienta externa LTI 1.3 manualmente

✅ Después de guardar, tu herramienta quedará disponible en la lista de herramientas preconfiguradas, lista para ser usada en cualquier curso.


🧪 Verificar la Integración desde Moodle

Una vez que tu herramienta LTI esté expuesta mediante ngrok y correctamente configurada como herramienta externa en Moodle, sigue estos pasos para probar su funcionamiento dentro de un curso:

  1. Accede a Moodle como docente e ingresa en el curso donde deseas probar la herramienta.
  2. Haz clic en el botón “Activar edición”.
  3. Selecciona “Añadir una actividad o recurso” y luego elige “Herramienta externa”.
  4. En el campo “Herramienta preconfigurada”, selecciona la integración que registraste previamente.
  5. Asigna un nombre a la actividad (por ejemplo, Demo LTI Node.js) y guarda los cambios.
  6. Haz clic sobre la actividad recién creada.
Moodle, añadir herramienta externa LTI 1.3 al curso
Moodle, añadir herramienta externa LTI 1.3 al curso

✅ Si todo está configurado correctamente, deberías ver la respuesta de tu servidor Express mostrando:

  • Tu nombre de usuario.
  • El rol con el que accediste (por ejemplo, Instructor o Estudiante).
  • El nombre del curso desde donde se lanzó la herramienta.
Moodle, prueba de herramienta externa LTI 1.3
Moodle, prueba de herramienta externa LTI 1.3

🛠 Errores Comunes y Cómo Solucionarlos

ErrorCausa PosibleSolución
Invalid stateEl state recibido no coincide con el guardado en sesión.Verifica que express-session esté activo y funcionando. Intenta en incógnito.
Issuer no válidoiss no coincide con el Platform ID de Moodle.Revisa que el Platform ID en tu código coincida exactamente con el de Moodle.
Client ID not foundEl client_id no coincide con el de Moodle.Verifica que estés usando el Client ID correcto.
Firma no válidaNo se pudo validar el id_token con la clave pública de Moodle.Revisa la JWKS URL y asegúrate de usar el kidcorrecto.
Redirect URI mismatchLa URI usada no está registrada en Moodle.Asegúrate de que las URIs coincidan exactamente (incluyendo el dominio ngrok).

5. Cierre y Siguientes Pasos

🎉 ¡Lo lograste! ¿Y ahora qué? ¡Felicidades! Acabas de dar el gran salto: ya tienes una integración LTI 1.3 funcionando entre Moodle y tu herramienta externa. 💥 No fue magia, fue código, configuración y un poco de paciencia… pero ahora sabes cómo conectar mundos.

Este no es el final, es el comienzo. Con esta base, puedes empezar a construir experiencias de aprendizaje más ricas, dinámicas y personalizadas. Y lo mejor: todo usando un estándar abierto que cada vez más plataformas educativas están adoptando.

🔧 ¿Qué puedes hacer ahora? 

Aquí van algunas ideas (con links para que no te pierdas):

✅ Enviar calificaciones a Moodle
Imagina que tu herramienta evalúa al estudiante y, automáticamente, la nota aparece en el libro de calificaciones de Moodle.
👉 Guía oficial: Assignment and Grade Services (IMS Global)

🔗 Permitir que los profes inserten contenido desde tu app
Con Deep Linking, un docente puede elegir un recurso específico (un quiz, un video, un simulador) y añadirlo directamente a su curso.
📚 Aprende más: LTI Deep Linking (IMS Global)

👥 Obtener la lista de estudiantes y roles
¿Quieres saber quiénes están en el curso? ¿Separar profes de alumnos? El servicio NRPS te lo da.
🔐 Documentación: Names and Role Provisioning Services

🌐 Conectar con Google, Microsoft, Zoom o tu propia API
Tu herramienta puede actuar como puente. Por ejemplo:

  • Abrir una reunión en Zoom con el contexto del curso.
  • Crear un documento en Google Drive con el nombre del estudiante y el curso.
  • Sincronizar datos con tu sistema interno de analítica.

💡 Usa LTI 1.3 como el «login seguro» que te abre la puerta a todo lo demás.


🚀 Recursos para seguir aprendiendo

📘 Especificación completa de LTI 1.3: IMS Global
🛠️ Repositorio de ejemplos (Node.js, Python, PHP): IMSGlobal GitHub
🧠 Foro de la comunidad Moodle LTI: Moodle.org Foro LTI
🎥 Tutoriales en video (en inglés): IMS Global YouTube

📣 En resumen: Conecta, personaliza, escala

No necesitas construir una plataforma gigante para aportar valor. A veces, con una pequeña herramienta bien integrada, cambias por completo la experiencia de aprendizaje.

Y ahora que ya sabes cómo funciona LTI 1.3…
👉 ¿Qué vas a integrar tú?

Puedes empezar pequeño, pero piensa en grande.
Y si en algún momento te atoras… tranquilo: todos los que hoy usan LTI 1.3 alguna vez estuvieron donde estás tú: mirando un id_token y preguntándose: «¿y ahora qué hago con esto?» 😄


❓ Preguntas Frecuentes (FAQs)

📌 ¿Qué versiones de Moodle soportan LTI 1.3?

Moodle 3.8 y versiones posteriores incluyen soporte nativo para LTI 1.3. Siempre se recomienda utilizar la versión más actualizada para garantizar compatibilidad, seguridad y acceso a las mejoras más recientes.

👩‍💼 ¿Debo ser administrador para configurar LTI 1.3 en Moodle?

Sí, necesitas permisos de administrador para registrar herramientas LTI, acceder a los servicios de interoperabilidad y modificar las configuraciones globales.

🛠️ ¿Puedo integrar una herramienta propia desarrollada desde cero?

¡Claro que sí! Esta guía justamente te enseña a crear una desde cero usando Node.js, pero puedes usar otros lenguajes también. LTI 1.3 es un estándar abierto y flexible.

🌍 ¿Qué pasa si mi URL de desarrollo cambia (por ejemplo, con ngrok)?

Debes actualizar manualmente los campos en Moodle cada vez que cambie tu URL pública. Para entornos productivos, considera un dominio propio o un subdominio estable.

🧾 ¿Cómo puedo enviar calificaciones desde mi app a Moodle?

Necesitas implementar el servicio Assignment and Grade Services (AGS) y asegurarte de que tu herramienta esté autorizada para ello durante la configuración inicial.

👥 ¿Cómo puedo obtener la lista de estudiantes y sus roles?

Implementa el servicio Names and Role Provisioning Services (NRPS). Moodle te enviará los datos del curso, incluyendo usuarios, roles y grupos si está habilitado.

🔒 ¿Qué mecanismos de seguridad usa LTI 1.3?

Usa OAuth 2.0OpenID ConnectJWTs y claves públicas expuestas vía JWKS. Todo el intercambio está basado en estándares modernos.

🔍 ¿Dónde encuentro más información oficial y ejemplos?

Entornos de Formación - edTech Solutions

🚀 ¿Quieres un Moodle que trabaje por ti?

Sabes que Moodle es una gran decisión. Pero para que sea una solución real, necesitas más que una simple instalación: una plataforma moderna, segura y alineada con tus procesos.

En Entornos de Formación llevamos más de 16 años ayudando a universidades, centros de FP y empresas a transformar Moodle en campus virtuales eficaces, escalables y automatizados.

🔧 ¿Qué podemos hacer por ti?

  • Instalación técnica completa en tu servidor (VPS o cloud), con configuración segura, backups automatizados y rendimiento optimizado (Apache, PHP, MySQL/MariaDB).
  • Diseño personalizado, que refleje tu identidad institucional o de marca, con un estilo actual y accesible.
  • Integración de plugins clave: videoconferencias, pasarelas de pago, gamificación, analítica, formularios avanzados, encuestas y automatizaciones.
  • Flujos personalizados: adaptamos Moodle a tus procesos, incluyendo automatizaciones con herramientas como Salesforce, Odoo o n8n.
  • Formación y acompañamiento real para que gestiones tu Moodle con autonomía desde el primer día.

🎯 ¿Te identificas con alguno de estos perfiles?

  • Laura, técnica TIC de una escuela: necesitas un Moodle accesible, multilingüe y adaptado al modelo pedagógico de tu centro.
  • Carlos, responsable de formación en empresa: buscas integrar formularios en Moodle conectados a RRHH, compliance o CRM interno.
  • Sofía, fundadora de una academia EdTech: quieres lanzar un campus visual, responsive y automatizado con lógica de negocio desde cero.

✅ ¿Por qué elegirnos?

Porque no nos limitamos a instalar Moodle. Diseñamos soluciones a medida que convierten tu plataforma en una verdadera herramienta de gestión, formación y automatización.

👉 Sin tecnicismos.
👉 Sin plantillas genéricas.
✅ Con resultados reales y soporte experto.


📩 ¿Hablamos?

Cuéntanos tu proyecto. ¿Es una universidad, una pyme, una administración pública, una startup o un centro educativo?

En Entornos de Formación te ayudamos a crear una plataforma Moodle alineada con tus objetivos, integrando formularios inteligentes, automatización y experiencia de usuario.

✉️ Escríbenos: andresmartinezsoto at gmail.com
🌐 Visítanos: www.edf.global

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *