Apple 登录配置
本指南介绍如何配置 Sign in with Apple,为用户提供安全、注重隐私的登录方式。
前置条件
- Apple 开发者账号(99 美元/年)
- 可访问 Apple Developer Portal
- 已安装 Xcode(iOS 应用)
步骤 1:创建 App ID
- 打开 Apple Developer Portal
- 进入 Certificates, Identifiers & Profiles
- 点击侧边栏 Identifiers
- 点击 + 添加新标识符
- 选择 App IDs,点击 Continue
- 选择 App 类型,点击 Continue
- 填写信息:
- Description:您的应用名称
- Bundle ID:显式(如
com.yourcompany.myapp)
- 在 Capabilities 中启用 Sign in with Apple
- 点击 Continue,然后 Register
步骤 2:创建 Services ID(Web 用)
Web 应用需要创建 Services ID:
- 进入 Identifiers
- 点击 +,选择 Services IDs
- 点击 Continue
- 填写信息:
- Description:"MyApp Web Login"
- Identifier:
com.yourcompany.myapp.web
- 点击 Continue,然后 Register
配置 Web 认证
- 在列表中找到您的 Services ID 并点击
- 启用 Sign in with Apple
- 点击 Configure
- 配置 Web 认证:
| 字段 | 值 |
|---|---|
| Primary App ID | 您的主 App ID |
| Domains | yourdomain.com |
| Return URLs | https://yourdomain.com/auth/apple/callback |
- 点击 Next > Done > Continue > Save
步骤 3:创建 Sign in with Apple 密钥
- 在侧边栏进入 Keys
- 点击 + 创建新密钥
- 输入密钥名称(如 "MyApp Sign in with Apple")
- 启用 Sign in with Apple
- 点击 Configure
- 选择 Primary App ID
- 点击 Save > Continue > Register
- 立即下载密钥文件(.p8)
重要: 密钥只能下载一次,请妥善保存。
- 记录:
- Key ID - 在密钥详情页显示
- Team ID - 在 Membership 中查找
步骤 4:生成 Client Secret
Apple 使用 JWT 作为 client secret,需自行生成:
所需信息
| 项 | 查找位置 |
|---|---|
| Team ID | Membership > Team ID |
| Key ID | Keys > 您的密钥 |
| Services ID | Identifiers > Services IDs |
| Private Key | 下载的 .p8 文件 |
生成 JWT
使用 Node.js 生成 client secret:
const jwt = require('jsonwebtoken');
const fs = require('fs');
const privateKey = fs.readFileSync('AuthKey_XXXXXXXXXX.p8');
const clientSecret = jwt.sign({}, privateKey, {
algorithm: 'ES256',
expiresIn: '180d',
audience: 'https://appleid.apple.com',
issuer: 'YOUR_TEAM_ID',
subject: 'com.yourcompany.myapp.web', // Services ID
keyid: 'YOUR_KEY_ID'
});
console.log(clientSecret);
注意: Client secret 会过期,请在过期前(最长 6 个月)重新生成。
步骤 5:在 OpenDev 中配置
- 登录 OpenDev 平台
- 进入 OAuth 渠道
- 添加或编辑 Apple OAuth 渠道
- 填写配置:
{
"provider": "apple",
"clientId": "com.yourcompany.myapp.signin",
"teamId": "YOUR_TEAM_ID",
"keyId": "YOUR_KEY_ID",
"privateKey": "[encrypted_private_key]",
"callbackUrl": "https://yourdomain.com/auth/callback?provider=apple",
"scopes": ["email", "name"]
}
说明:
privateKey需用项目加密工具加密后再存入数据库- 统一回调格式为
/auth/callback?provider=apple(POST)- Web 弹窗模式可省略 teamId、keyId、privateKey、callbackUrl
- 也支持使用
appSecret作为privateKey的别名
配置字段
| 字段 | Web 弹窗 | 服务端认证 | 说明 |
|---|---|---|---|
| Client ID | 必填 | 必填 | Services ID |
| Team ID | 可选 | 必填 | Apple 开发者 Team ID |
| Key ID | 可选 | 必填 | Sign in with Apple 密钥 ID |
| Private Key | 可选 | 必填 | .p8 文件的加密内容 |
| Callback URL | 可选 | 必填 | 授权码模式的重定向 URL |
| Scopes | 可选 | 可选 | 请求的数据(email, name) |
加密 Private Key
存入前使用以下命令加密:
cd backend
node scripts/tools/encrypt-apple-key.js ../configure/AuthKey_XXXXXXXXXX.p8
将加密输出填入数据库配置的 privateKey 字段。
步骤 6:iOS 实现
在 Xcode 中添加能力:
- 在 Xcode 中打开项目
- 选择 target
- 进入 Signing & Capabilities
- 点击 + Capability
- 添加 Sign in with Apple
步骤 7:测试集成
iOS 测试
- 使用真机(模拟器无法测试 Sign in with Apple)
- 使用 Apple ID 登录
- 验证认证流程
Web 测试
- 访问您的 Web 应用
- 点击「通过 Apple 登录」
- 完成 Apple 认证
- 验证回调收到用户数据
OAuth 响应示例
{
"provider": "apple",
"providerId": "001234.abc123def456.0123",
"email": "user@privaterelay.appleid.com",
"name": "John D.",
"emailVerified": true
}
注意: Apple 仅在首次授权时返回姓名和邮箱,请立即保存。
故障排查
错误:invalid_client
解决: 核对 Services ID 与 Client ID;检查 private key 格式;确认 client secret JWT 未过期。
错误:invalid_grant
解决: 授权码可能已过期(5 分钟)或已被使用;确认 redirect URI 完全一致。
未收到用户信息
解决: 姓名和邮箱仅在首次授权时发送,检查用户是否曾授权过该应用。
安全最佳实践
- 保护 Private Key - 勿在客户端代码中暴露
- 验证 ID Token - 验证 Apple 的 JWT 签名
- 校验 Nonce - 防止重放攻击
- 处理撤销 - 监听凭证撤销通知
- 轮换密钥 - 在过期前生成新的 client secret