
本文详解 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 标准的学习工具(LTI Tool)时,开发者常面临一个核心问题:如何安全、合规地获取当前登录用户的详细身份信息(如姓名、邮箱、角色、所属课程等)? 尤其当工具需跨多个 LMS(如 Moodle、Canvas、Brightspace)部署时,必须严格遵循 LTI 1.3 安全框架,而非自行构造 API 调用。以下从原理到实践,系统梳理关键机制。
✅ 正确获取用户信息的两条标准路径
1. 解析 Launch JWT 中的 User Identity Claims(推荐首选)
LTI 1.3 启动流程(Launch)本身即携带经过签名和加密的 JWT,其中已包含基础但关键的用户身份声明(Claims)。这些字段由 LMS 在发起 Launch 时注入,无需额外 Token 请求,零延迟、高可靠、强制支持。
典型用户相关 Claim 示例(均位于 JWT Payload 中):
{
"https://purl.imsglobal.org/spec/lti/claim/user_id": "u123456",
"https://purl.imsglobal.org/spec/lti/claim/given_name": "Alice",
"https://purl.imsglobal.org/spec/lti/claim/family_name": "Smith",
"https://purl.imsglobal.org/spec/lti/claim/email": "alice.smith@school.edu",
"https://purl.imsglobal.org/spec/lti/claim/roles": [
"http://purl.imsglobal.org/vocab/lis/v2/membership#Instructor"
],
"https://purl.imsglobal.org/spec/lti/claim/context": {
"id": "course-789",
"label": "Biology 101",
"title": "Introductory Biology"
}
}✅ 优势:无需额外网络请求;所有 LTI 1.3 兼容平台(含 Moodle)均保证提供 user_id、email 和 roles;适合快速渲染用户界面或做权限判断。
⚠️ 注意:given_name/family_name 等字段为可选,LMS 可能不返回,不可作为唯一标识依据。
2. 调用 Names and Role Provisioning Service(NRPS)获取完整成员列表
当需要获取当前课程(Context)内所有成员(如全班学生名单、助教列表),或需获取 Launch JWT 中未包含的扩展属性(如用户名 username、头像 URL、所在部门)时,应使用 NRPS 服务。
该服务需独立认证,流程如下:
-
申请带 NRPS Scope 的 Access Token
向 LMS 的 Token Endpoint(如你访问的https://localhost/mod/lti/token.php)发送请求,必须显式指定 scope:POST /mod/lti/token.php HTTP/1.1 Content-Type: application/x-www-form-urlencoded grant_type=client_credentials client_id=your_tool_client_id client_secret=your_tool_secret scope=https://purl.imsglobal.org/spec/lti-nrps/scope/contextmembership.readonly
? 错误做法:省略
scope参数,或注释掉token.php中的 scope 校验逻辑——这将导致返回的 Token 无权访问 NRPS,后续调用必返回403 Forbidden。 -
调用 NRPS 成员端点
使用上一步获取的 Access Token,请求:GET /lti/nrps/v2/contexts/{context_id}/members HTTP/1.1 Authorization: Bearer <access_token>响应示例(精简):
{ "members": [ { "user_id": "u123456", "name": "Alice Smith", "email": "alice.smith@school.edu", "picture": "https://moodle.example.com/pluginfile.php/.../u123456.jpg", "roles": ["Instructor"], "status": "Active" } ] }
? auth.php 与 token.php 的核心分工(以 Moodle 为例)
| 文件 | 作用 | 触发时机 | 是否需手动调用 |
|---|---|---|---|
auth.php |
OpenID Connect 认证端点 处理 OIDC Authorization Code Flow 的 /authorize 请求,重定向用户至 LMS 登录页并返回授权码(code) |
LTI 工具首次启动时,浏览器自动跳转 | ❌ 不应直接在 Postman 中调用;它是 OIDC 流程的入口,非 REST API |
token.php |
OAuth 2.0 Token 端点 接收授权码( code)或客户端凭证(client_credentials),返回 access_token(用于调用 NRPS、Deep Linking 等服务) |
工具后端用 code 换 token,或用 client_credentials 直接申请服务 Token |
✅ 是开发者需主动集成的 API,但必须携带正确 scope |
? 提示:你当前在 Postman 中手动构造 JWT 并调用
token.php,本质上是模拟client_credentials流。此时scope参数不可或缺——它告诉 LMS:“我申请的 Token 仅用于读取成员信息”,LMS 据此颁发最小权限 Token。
⚠️ 关键注意事项与最佳实践
-
绝不绕过标准流程:不要尝试通过修改
token.php源码、注释 scope 校验来“跳过”权限控制。这违反 LTI 安全规范,且在生产环境(如 Canvas、D2L)中必然失败。 -
用户标识一致性:LMS 传递的
user_id和email必须与 Microsoft Entra ID 或学校目录中的 UPN/主邮箱完全一致,否则 Microsoft 365 LTI 集成(如 OneNote 笔记本自动填充)将无法匹配用户。 -
Token 有效期管理:
access_token通常有效期为 1 小时,需实现刷新逻辑(若支持refresh_token)或重新请求。 -
Moodle 特别提示:确保 Moodle 站点已启用
LTI Advantage并配置了Names and Roles Provisioning Service,否则/nrps/v2/...端点将返回404。
✅ 总结:你的下一步行动清单
-
验证 Launch JWT:在工具接收 Launch 请求后,先解析 JWT,提取
user_id、email、roles,满足基础身份展示需求; -
按需调用 NRPS:若需全班名单或扩展属性,在服务端使用
client_credentials流,向token.php发送带contextmembership.readonlyscope 的请求; -
弃用
auth.php手动调用:它不属于工具后端 API,而是前端重定向链路的一环; - 查阅官方规范:精读 IMS LTI 1.3 Core Spec § User Identity Claims 和 NRPS Spec § Scope。
遵循此路径,你的 LTI 工具将具备跨平台兼容性、企业级安全性,并顺利对接 Microsoft 365 教育生态(如作业成绩同步、Teams 自动建群等高级场景)。

















