
本文详解 LTI 1.3 工具中获取用户身份(如姓名、角色、邮箱)和课程成员信息的两种标准方式:通过 Launch JWT 解析用户声明,以及调用 Names and Role Provisioning Service(NRPS)获取完整上下文成员列表,并说明 auth.php 与 token.php 的核心作用及正确 scope 配置方法。
本文详解 lti 1.3 工具中获取用户身份(如姓名、角色、邮箱)和课程成员信息的两种标准方式:通过 launch jwt 解析用户声明,以及调用 names and role provisioning service(nrps)获取完整上下文成员列表,并说明 `auth.php` 与 `token.php` 的核心作用及正确 scope 配置方法。
在构建符合 IMS Global LTI 1.3 标准的学习工具时,准确、安全地获取用户身份与课程上下文信息是实现个性化体验(如自动创建 OneNote 笔记本、同步成绩、权限控制)的前提。许多开发者(尤其是初次集成 Moodle 或其他 LMS 的开发者)容易混淆两个关键端点 auth.php 和 token.php 的职责,或误以为需手动调用 /token.php 即可直接获取用户数据——这恰恰违背了 LTI 1.3 的安全设计原则。
✅ 正确路径一:从 Launch JWT 中提取基础用户身份
LTI 1.3 的启动流程(OpenID Connect Launch)是整个集成的起点。当教师在 LMS(如 Moodle)中点击你的工具链接时,LMS 会向你的工具发起一个 JWT 签名的 POST 请求(通常发往你的 launch.php 或 /login 端点),该 JWT 已由 LMS 使用其私钥签名,并包含一组标准化的用户身份声明(Claims)。
你无需额外调用 token.php 即可获得以下关键用户信息(均位于 JWT Payload 中):
{
"https://purl.imsglobal.org/spec/lti/claim/user_id": "12345",
"https://purl.imsglobal.org/spec/lti/claim/roles": [
"http://purl.imsglobal.org/vocab/lis/v2/membership#Instructor"
],
"https://purl.imsglobal.org/spec/lti/claim/name": "Jane Doe",
"https://purl.imsglobal.org/spec/lti/claim/given_name": "Jane",
"https://purl.imsglobal.org/spec/lti/claim/family_name": "Doe",
"https://purl.imsglobal.org/spec/lti/claim/email": "jane.doe@school.edu",
"https://purl.imsglobal.org/spec/lti/claim/context": {
"id": "course-789",
"label": "Biology 101",
"title": "Introductory Biology"
}
}✅ 操作建议:
- 在你的 Launch 处理逻辑中,使用标准 JWT 库(如
firebase/php-jwt或 Python 的PyJWT)验证并解析该 JWT; - 严格校验
iss(issuer)、aud(audience)、exp(过期时间)及签名; - 直接读取上述
claim字段,即可完成用户身份识别与课程上下文绑定。
⚠️ 注意:
auth.php是 LMS 内部用于 OpenID Connect 授权码交换的端点(即 OIDC Authorization Endpoint),不应由工具端主动调用。它由 LMS 在 Launch 流程中内部调用 Identity Provider(如 Microsoft Entra ID)完成认证。你作为工具开发者,只需正确配置.well-known/openid-configuration并处理好 Launch JWT 即可。
✅ 正确路径二:通过 NRPS 服务获取完整成员列表
若需获取当前课程中所有学生、助教、教师的详细信息(例如为 OneNote 课堂笔记本批量创建页面、设置文件协作权限),则需调用 LTI 的 Names and Role Provisioning Service(NRPS)。
该服务要求:
-
先获取访问令牌(Access Token):调用 LMS 提供的 Token Endpoint(如你本地的
https://localhost/mod/lti/token.php),但必须携带正确的 scope; - 使用该 Token 调用 NRPS 成员接口。
? 关键:Scope 必须显式声明
你提到“未提供 scope 导致无法获取用户详情”,这正是核心问题。NRPS 的标准只读 scope 为:
https://purl.imsglobal.org/spec/lti-nrps/scope/contextmembership.readonly
因此,向 token.php 发起请求时,scope 参数不可省略,且必须精确匹配(大小写敏感)。示例请求体(application/x-www-form-urlencoded):
grant_type=client_credentials client_id=your_tool_client_id client_secret=your_tool_client_secret scope=https://purl.imsglobal.org/spec/lti-nrps/scope/contextmembership.readonly
✅ 成功响应后,你将获得一个短期有效的 Bearer Token,随后即可调用 NRPS 成员端点(URL 通常在 Launch JWT 的 https://purl.imsglobal.org/spec/lti-nrps/claim/names_roles_service 声明中提供):
curl -X GET \ -H "Authorization: Bearer <ACCESS_TOKEN>" \ "https://localhost/mod/lti/nrps/membership?limit=100"
响应示例:
{
"members": [
{
"status": "Active",
"user_id": "12345",
"name": "Jane Doe",
"email": "jane.doe@school.edu",
"roles": ["Instructor"],
"picture": "https://..."
}
]
}? 为什么不要注释掉 scope 或绕过规范?
- 注释
token.php中的 scope 校验(如你所做)会破坏 LTI 安全模型,导致令牌无明确权限边界,LMS 可能拒绝后续服务调用; - LTI 1.3 强制基于 scope 的最小权限原则(Principle of Least Privilege),未声明
contextmembership.readonly,NRPS 接口将返回 403 Forbidden; - 所有主流 LMS(Moodle、Canvas、Brightspace、Schoology)均严格遵循此规范,生产环境必须合规。
✅ 总结:三步落地建议
| 步骤 | 操作 | 工具端责任 |
|---|---|---|
| 1. 启动处理 | 验证并解析 Launch JWT | ✅ 提取 user_id, email, roles, context.id 等基础字段 |
| 2. 权限申请 | 向 LMS Token Endpoint 发送含正确 scope 的请求 | ✅ 使用 contextmembership.readonly 获取 NRPS 访问权 |
| 3. 成员拉取 | 用 Access Token 调用 NRPS Membership API | ✅ 分页获取全量课程成员,支撑 OneNote/Teams/OneDrive 等深度集成 |
? 补充提示:Microsoft 365 LTI 应用已全面采用此模式——其 OneNote 课堂笔记本自动填充、Teams 课程团队同步、作业成绩回传等功能,全部依赖 Launch JWT 的即时身份识别 + NRPS 的全量成员同步。截至 2026 年 9 月,所有经典 LTI 工具(如旧版 OneDrive LTI)已停用,新部署必须严格遵循 LTI 1.3 Advantage 规范。
通过以上结构化实践,你将构建出既符合 IMS Global 标准、又具备生产级稳定性的 LTI 1.3 工具,无缝接入 Moodle、Canvas、Blackboard、Brightspace、Schoology 及所有 LTI 1.3 Advantage 兼容平台。

















