ltijs问题:向LMS返回数据时Deep Linking陷入停滞
问题分析与修复方案
核心问题
你的Deep Linking流程在表单提交到LMS后超时,本质是Deep Linking上下文Token未被正确传递到POST请求处理逻辑,导致生成的提交表单缺少LMS验证所需的关键参数,最终触发超时错误。
具体修复步骤
1. 持久化Deep Linking Token到Session
lti.onDeepLinking中获取的Token包含了deep_link_redirect_url、签名密钥等核心上下文,但当前代码未将其持久化,导致POST请求时无法获取有效Token生成合法表单。修改如下:
lti.onDeepLinking((token, req, res) => { console.log("DEEP LINKING", token); // 将Token存入Session,跨请求传递上下文 req.session.deepLinkToken = token; lti.redirect(res, '/deeplink') }) // GET请求展示内容选择页 lti.app.get("/deeplink", async (req, res) => { // 校验Session中的Token,拦截非法访问 if (!req.session.deepLinkToken) return res.status(403).send("无效的深度链接请求"); res.sendFile(path.join(__dirname, '/public/select.html')) });
2. 使用Session中的Token生成提交表单
在POST请求处理逻辑中,替换res.locals.token为Session中存储的有效Token:
// POST提交选中的内容项 lti.app.post("/deeplink", async (req, res) => { const resource = req.body; const token = req.session.deepLinkToken; // 二次校验Token有效性 if (!token) return res.status(403).send("无效的深度链接请求"); const items = [ { type: 'ltiResourceLink', title: resource.product, url: `${toolUrl}/lti/launch`, custom: { product: resource.product } } ] const form = await lti.DeepLinking.createDeepLinkingForm(token, items, { message: '资源注册成功!' }) console.log("返回自动提交表单", form); // 清理Session中的Token,防止重复使用 delete req.session.deepLinkToken; return res.send(form); })
3. 配置Express Session(关键缺失项)
ltijs依赖Express Session存储上下文,但当前代码未配置Session,导致Token无法持久化。需在lti.setup前添加Session配置:
const express = require('express'); const session = require('express-session'); const MongoStore = require('connect-mongo'); // 初始化Express实例并配置Session const app = express(); app.use(session({ secret: 'your-random-secure-secret', // 替换为随机安全密钥 resave: false, saveUninitialized: false, store: MongoStore.create({ mongoUrl: "mongodb://127.0.0.1:3001/lticlient" }), cookie: { secure: false, sameSite: "None" } })); // 修改ltijs.setup,传入配置好Session的Express实例 lti.setup(ltiKey, { url: "mongodb://127.0.0.1:3001/lticlient", }, { app: app, // 传入自定义App实例 appRoute: "/lti/launch", loginRoute: "/lti/login", cookies: { secure: false, sameSite: "None" }, devMode: true, keysetRoute: "/lti/keys", });
4. 额外排查验证
- LMS配置检查:确认Moodle/Canvas中工具的Deep Linking权限已开启,
deep_link_redirect_url与工具配置完全一致 - 网络请求日志:通过浏览器开发者工具查看提交到LMS的POST请求,确认表单包含
id_token、deep_link_settings等关键参数 - 签名有效性:查看LMS的LTI日志(如Moodle的LTI调试日志),检查签名验证是否失败
内容的提问来源于stack exchange,提问作者Davide
相关产品推荐
相关产品推荐

