Highlight
Sign in with Apple 最初只支持个人 Apple ID。这次更新将其扩展到 Managed Apple ID——由组织(学校或企业)通过 Apple School Manager 或 Apple Business Manager 管理的账号。这意味着学生、教师和员工可以用他们的 Managed Apple ID 一键登录你的 App。
核心内容
学校和企业里的登录问题,和个人 App 不一样。
个人用户用 Sign in with Apple 时,可以编辑姓名,也可以隐藏邮箱。组织账号的诉求更直接:App 需要知道是谁在登录,然后给他正确的权限。Slack 的例子很典型。员工用工作账号登录后,Slack 需要根据姓名和邮箱判断他能进入哪些频道。(02:15)
WWDC 2022 的变化是:Sign in with Apple 支持 Managed Apple ID。Managed Apple ID 由组织拥有,通过 Apple School Manager 或 Apple Business Manager 管理。学生、教师、员工可以用这类账号登录支持 Sign in with Apple 的 App。(01:10)
对于教育类 App,登录只是第一步。老师要发作业和通知,系统还需要提前导入学生、教师和班级。如果一个学区有几百或几千个学生,IT 管理员手工录入会很慢。Roster API 就是为这件事准备的:它让 App 通过 REST 端点读取 Apple School Manager 里的用户和班级数据。(05:35)
整个流程分三层:
- 用户用 Managed Apple ID 登录 App。
- IT 管理员通过 OAuth 2.0 同意共享组织数据。
- App 后端用访问令牌调用 Roster API,导入用户和班级。
这场 Session 没有官方 Code tab 代码片段。下面的示例都按演讲展示的字段和流程整理,属于概念代码,用来说明请求结构,不代表 Apple 文档中的完整端点地址或 SDK 签名。
详细内容
Managed Apple ID 登录时,姓名和邮箱的处理方式
(03:12)使用 Sign in with Apple at Work & School 时,App 可以访问姓名和邮箱字段。前提是授权请求包含 full name 和 email scopes。
演讲还提醒了一个边界情况:有些学校不会给年幼学生分配邮箱。遇到这种账号时,账号创建界面只显示姓名,邮箱不存在。(04:18)
概念流程:成功授权后读取登录结果中的字段
userIdentifier = authorizationResult.user
fullName = authorizationResult.fullName
email = authorizationResult.email
saveOrUpdateAccount(
stableUserID: userIdentifier,
displayName: fullName,
emailAddress: email
)
关键点:
userIdentifier是稳定用户标识,后面可与 Roster API 返回的用户标识对应起来。fullName来自授权结果;Managed Apple ID 登录场景下,App 需要它做组织内身份识别。email可能不存在,教育场景尤其要处理空值。stableUserID应作为账号关联主键,邮箱更适合做展示或辅助匹配。
如果你已经实现 Sign in with Apple,不需要额外工作来支持 Managed Apple ID。Apple 在这次发布中把已有登录体验扩展到了组织账号。(05:04)
在 Developer Portal 里申请组织数据 scope
(08:24)Roster API 的接入先从 Developer Portal 开始。开发者进入 Certificates, Identifiers & Profiles,在 Account & Organizational Data Sharing 下配置主 App ID,并选择需要的 Organizational Data Sharing scopes。
本次发布提供两个 scope:
- user access:访问用户数据。
- class access:访问班级数据。
同时要配置 return URLs。后续 OAuth 2.0 授权完成后,授权码会回到这些 URL。(08:51)
# 概念清单:Developer Portal 配置项
Primary App ID: com.example.education-app
Organizational Data Sharing Scopes:
- user access
- class access
Return URLs:
- https://example.com/apple-school-manager/callback
关键点:
Primary App ID绑定请求组织数据的 App。user access决定后端能否读取 Apple School Manager 中的用户信息。class access决定后端能否读取班级及其成员关系。Return URLs会进入 OAuth 2.0 授权流程,配置错误会导致授权码无法回到你的服务端。
用 OAuth 2.0 获取 Roster API 访问令牌
(09:47)第二步是让 IT 管理员授权。演讲里的例子是 App 提供一个“Connect to Apple School Manager”按钮,管理员点击后进入 OAuth 2.0 流程。
第一个请求是 GET authorize endpoint。请求包含 client_id、redirect_uri、state、response_type 和 scopes。响应会把管理员带到 Apple 的同意界面。(10:16)
# 概念请求:启动授权流程
GET {authorize endpoint}?
client_id={your-client-id}&
redirect_uri={registered-return-url}&
state={csrf-protection-token}&
response_type=code&
scope={requested-organizational-data-scopes}
关键点:
client_id标识请求数据访问的 App。redirect_uri必须匹配 Developer Portal 里配置的 return URL。state用来在回调时校验请求来源,避免串改授权流程。response_type=code表示请求授权码。scope对应前面申请的组织数据访问范围。
管理员点击 Allow 后,Apple 会把授权码传给你的 return URL。随后 App 后端向 token endpoint 发 POST 请求,用授权码换取 access token、过期时间和 refresh token。(11:08)
# 概念请求:用授权码换取访问令牌
POST {token endpoint}
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code={authorization-code-from-return-url}&
redirect_uri={registered-return-url}&
client_id={your-client-id}
关键点:
authorization_code来自管理员同意后的回调。redirect_uri继续使用注册过的 return URL。- 响应包含
access token,后续调用 Roster API 时放入 Authorization header。 - 响应还包含
refresh token,access token 过期后用它换新令牌。
刷新令牌也是 POST token endpoint。演讲明确说,请求体包含标准 OAuth 参数和 refresh token,响应返回新的 access token 及过期时间。(11:49)
# 概念请求:用 refresh token 更新访问令牌
POST {token endpoint}
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&
refresh_token={refresh-token}&
client_id={your-client-id}
关键点:
grant_type=refresh_token表示这次不是重新让管理员授权。refresh_token应保存在服务端,不应暴露给客户端。- 新的
access token继续用于读取用户和班级。
调用 users endpoint 导入学生、教师和员工
(12:18)当前发布包含五类 Roster API 查询:获取班级列表、获取用户列表、获取特定班级、获取特定用户、获取某个班级里的用户。
演讲先展示 users endpoint。它有三个查询参数:pageToken、limit 和可选的 role。pageToken 与 limit 用于分页,role 可筛选 students、instructors 或 staff。请求头需要带上前面 OAuth 流程生成的 access token。(12:53)
# 概念请求:读取最多 10 个学生
GET {users endpoint}?limit=10&role=students
Authorization: Bearer {access-token}
关键点:
limit=10控制单次响应里最多返回多少用户。role=students把结果限定为学生。Authorizationheader 使用 OAuth 2.0 access token。- 第一次请求可以不传
pageToken。
响应是 JSON payload,包含 users、nextPageToken 和 moreToFollow。用户对象包含 givenName、familyName、email、roles 等信息。演讲特别指出,响应里还有稳定的用户唯一标识,它和用户通过 Sign in with Apple 认证时 App 收到的标识相同。(13:14)
{
"users": [
{
"id": "stable-user-identifier",
"givenName": "Fatima",
"familyName": "Silva",
"email": null,
"roles": ["student"]
}
],
"nextPageToken": "next-page-token",
"moreToFollow": true
}
关键点:
users是当前页的用户数组。id是稳定用户标识,可与 Sign in with Apple 登录结果关联。email可能为null,账号模型不能强依赖邮箱。nextPageToken用于下一次分页请求。moreToFollow为true时,说明还有下一页。
调用 classes endpoint 建立班级关系
(14:24)导入用户后,App 后端再请求 classes endpoint。它返回学区里的班级列表,以及班级和学生、教师之间的关系。
classes 请求包含 pageToken 和 limit 两个查询参数。请求头和 users endpoint 相同,都要带 access token。(14:45)
# 概念请求:读取最多 200 个班级
GET {classes endpoint}?limit=200&pageToken={next-page-token}
Authorization: Bearer {access-token}
关键点:
limit=200对应演讲中的示例规模。pageToken表示这次请求处在分页导入过程中。Authorizationheader 继续使用同一个授权流程得到的 access token。
响应里的 classes 包含班级名称、班级标识、教师 ID 列表和学生 ID 列表。这样 App 可以把前面导入的用户和班级关联起来。(15:10)
{
"classes": [
{
"id": "class-identifier",
"name": "Biology 101",
"instructorIds": ["teacher-user-id"],
"studentIds": ["student-user-id-1", "student-user-id-2"]
}
]
}
关键点:
classes是当前页的班级数组。id是班级标识,用来更新或去重本地班级记录。instructorIds引用教师用户 ID。studentIds引用学生用户 ID。- 这些 ID 让 App 能构建“老师—班级—学生”的本地关系表。
IT 管理员有两层访问控制
(15:47)组织数据由组织负责管理。个人 Sign in with Apple 是用户自己决定使用哪些 App;Work & School 场景下,IT 管理员要替组织控制哪些 App 可以登录,哪些 App 可以访问组织数据。
Apple School Manager、Apple Business Manager 和 Business Essentials 提供相同的控制模式:
- Allow all apps:组织内用户可以用支持 Sign in with Apple 的所有 App 登录。
- Allow only certain apps:管理员把允许的 App 加入列表,列表外 App 会显示错误。(16:50)
Organizational Data Sharing 也有相同模式。管理员可以限制只有特定 App 能通过 Roster API 访问用户和班级信息。这是同意界面之外的第二层控制。(17:56)
组织侧访问控制
Sign in with Apple at Work & School:
- Allow all apps
- Allow only certain apps
Organizational Data Sharing:
- Allow all apps
- Allow only certain apps
- IT admin consent screen
关键点:
- 登录权限和组织数据访问权限是两组控制。
- “Allow only certain apps” 会把可用 App 限定在管理员维护的列表中。
- Roster API 访问需要管理员同意,也受 Organizational Data Sharing 访问模式限制。
- 接入教育组织时,开发者要把管理员授权和访问控制说明写进 onboarding 流程。
核心启发
1. 给教育 App 做一键开学导入
- 做什么:让管理员点击“Connect to Apple School Manager”,自动导入学生、教师和班级。
- 为什么值得做:Roster API 解决了开学前手工录入几百或几千个账号的问题。
- 怎么开始:先申请 user access 和 class access,再实现 OAuth 2.0 授权流程,最后分页调用 users 与 classes endpoints。
2. 用稳定用户 ID 合并登录账号和花名册账号
- 做什么:学生第一次用 Managed Apple ID 登录时,自动找到 Roster API 中对应的用户记录。
- 为什么值得做:演讲说明 Roster API 返回的稳定用户标识,和 Sign in with Apple 认证时 App 收到的标识相同。
- 怎么开始:账号表以 Sign in with Apple 的 user identifier 为主键,Roster 导入时用同一个标识更新姓名、角色和班级关系。
3. 为无邮箱学生设计账号模型
- 做什么:允许学生账号没有邮箱,只显示姓名和班级信息。
- 为什么值得做:Apple 明确提到,有些学校不会给年幼学生分配邮箱。
- 怎么开始:把邮箱字段设为可空;登录、导入、通知设置都以稳定用户 ID 和组织角色为核心。
4. 给 IT 管理员做权限排障页
- 做什么:在后台显示当前是否获得 user access、class access,以及管理员是否允许 App 访问组织数据。
- 为什么值得做:Roster API 访问同时受 OAuth 同意界面和 Organizational Data Sharing 访问控制影响。
- 怎么开始:在授权失败、令牌刷新失败、接口返回拒绝时,把错误归类到“未授权”“scope 不足”“组织侧未允许 App”三类提示。
5. 为班级同步做增量任务
- 做什么:定时分页同步 users 和 classes,更新本地学生名单与任课教师关系。
- 为什么值得做:Roster API 的响应设计包含分页字段,适合后端批量导入和持续同步。
- 怎么开始:保存
nextPageToken、同步时间和本地导入版本;每次同步完成后再切换线上班级数据。
关联 Session
- Enhance your Sign in with Apple experience — 讲 iOS 16 里 Sign in with Apple 的账号发现和账号关联体验,适合补登录侧细节。
- Get the most out of Sign in with Apple — 回顾 Sign in with Apple 的完整集成、ID Token、Web 流程和隐私能力。
- What’s new in managing Apple devices — 同属组织管理主题,覆盖 WWDC22 的身份技术和 Apple 设备管理更新。
- Adopt declarative device management — 继续看企业和学校设备管理侧的声明式 MDM 模型。
评论
GitHub Issues · utterances