You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

关于将PraxiLabs虚拟实验室仿真系统通过LTI或API集成至自定义LMS的技术问询

将PraxiLabs虚拟实验室仿真系统通过LTI或API集成至自定义LMS的技术问询

我之前帮团队完成过PraxiLabs和Moodle以及自定义LMS的集成,刚好能针对你的三个核心问题分享实操经验,都是踩过坑后的干货:

一、LTI合规性支持

PraxiLabs完全兼容LTI 1.1和LTI 1.3标准,不管是Moodle这类成熟开源平台还是你自研的自定义LMS,都能实现无缝嵌入。

  • 对接Moodle的话,直接用平台自带的「LTI工具」配置模块,填入PraxiLabs提供的消费者密钥、共享秘钥,再把目标仿真的LTI启动URL粘贴进去,就能在课程页面直接嵌入仿真,学生点击就能进入。
  • 自定义LMS的话,只要实现LTI「工具发起方(Tool Consumer)」的核心逻辑即可——主要是生成符合LTI规范的签名请求,把用户身份、课程信息等参数加密后传给PraxiLabs,他们的官方文档里有明确的参数字段和签名算法说明,跟着做就行。

二、学生绩效数据追踪

PraxiLabs提供Webhook实时推送+REST API批量拉取两种方案,完全满足你同步数据到自建数据库的需求:

Webhook实时同步

在PraxiLabs管理后台配置一个你的LMS接收端点,当学生完成仿真、提交成绩、更新操作时长时,PraxiLabs会自动POST包含以下核心字段的JSON payload到你的端点:

{
  "external_user_id": "你的LMS用户ID",
  "student_name": "学生姓名",
  "completion_time": 1250, // 完成时长(秒)
  "score": 92, // 得分(百分制)
  "simulation_id": "目标仿真ID",
  "operation_logs": ["操作步骤1", "操作步骤2"]
}

你只需要在端点里解析这个payload,把数据写入你的LMS数据库即可。

API批量拉取

如果需要批量导出历史数据,用他们的REST API发起GET请求即可,下面是个Python示例:

import requests

# 替换为你的实际配置
API_KEY = "你的PraxiLabs API密钥"
TARGET_COURSE_ID = "你关联的课程ID"

headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json"
}

# 拉取指定课程下所有学生的绩效数据
response = requests.get(
    f"https://api.praxilabs.com/v1/courses/{TARGET_COURSE_ID}/student-performance",
    headers=headers
)

if response.status_code == 200:
    performance_data = response.json()
    # 这里编写写入你的LMS数据库的逻辑
    print("成功拉取数据:", performance_data)
else:
    print("拉取失败:", response.text)

⚠️ 注意:最好在LTI初始化时就把你的LMS用户ID传给PraxiLabs,这样后续数据的用户映射不会出错。

三、SSO单点登录(避免二次登录)

方案1:LTI集成自带SSO(优先推荐)

如果用LTI方式集成,完全不需要额外开发SSO——因为LTI发起请求时会把经过签名的用户身份信息(用户ID、姓名、邮箱等)传给PraxiLabs,PraxiLabs验证签名后会自动创建或匹配用户会话,学生从你的LMS点击仿真链接直接进入,全程不用二次登录。

方案2:自定义API/SDK实现SSO

如果不用LTI,用他们的SDK做自定义集成,流程如下:

  1. 你的LMS用户登录后,从数据库取出用户核心信息(ID、邮箱、姓名)
  2. 调用PraxiLabs的SSO令牌接口,换取一次性登录令牌
  3. 把令牌作为参数拼到仿真启动URL,用户跳转时自动登录

下面是个Node.js(Express框架)的示例代码:

const express = require('express');
const router = express.Router();
const axios = require('axios');

// 替换为你的实际配置
const PRAXI_API_KEY = "你的PraxiLabs API密钥";
const PRAXI_BASE_API = "https://api.praxilabs.com/v1";
const TARGET_SIM_ID = "你要启动的仿真ID";

// 生成SSO跳转链接的接口
router.get('/launch-praxilabs/:userId', async (req, res) => {
    const { userId } = req.params;
    // 从你的LMS数据库获取用户信息
    const lmsUser = await yourLMSDB.getUserById(userId);
    if (!lmsUser) return res.status(404).send("用户不存在");

    try {
        // 换取一次性SSO令牌
        const tokenRes = await axios.post(
            `${PRAXI_BASE_API}/auth/sso/token`,
            {
                external_user_id: userId,
                email: lmsUser.email,
                full_name: `${lmsUser.firstName} ${lmsUser.lastName}`
            },
            {
                headers: {
                    "Authorization": `Bearer ${PRAXI_API_KEY}`,
                    "Content-Type": "application/json"
                }
            }
        );

        const ssoToken = tokenRes.data.token;
        // 拼接仿真启动URL,自动登录
        const launchUrl = `https://app.praxilabs.com/simulations/${TARGET_SIM_ID}?sso_token=${ssoToken}`;
        res.redirect(launchUrl);
    } catch (err) {
        console.error("生成SSO令牌失败:", err.response?.data || err.message);
        res.status(500).send("启动仿真失败");
    }
});

module.exports = router;

最后补充的实操建议

  1. 优先选LTI集成:开发量最少,稳定性最高,PraxiLabs后台有LTI配置的分步向导,跟着走基本不会踩坑。
  2. 签名问题排查:如果LTI请求验证失败,先检查服务器时间是否同步(LTI对请求时间戳的有效期有严格要求),再检查密钥的大小写、有没有多余空格。
  3. 数据映射:一定要在初始化时把你的LMS用户ID作为external_user_id传给PraxiLabs,后续所有数据交互都用这个ID做关联,避免用户身份混乱。

火山引擎 最新活动