Apple开发_整合 Sign in with Apple (SIWA) 的订阅系统完整流程和可视化图表

🔑 关键流程原则

  1. 先登录后订阅:强制用户先通过Apple ID登录
  2. 绑定订阅到Apple ID:而非设备
  3. 自动恢复:同一Apple ID跨设备自动同步订阅状态

📱 用户操作流程图

sequenceDiagram participant 用户 participant App participant Apple服务器 participant 你的服务器 用户->>App: 点击「订阅会员」 App->>用户: 弹出Sign in with Apple授权页 用户->>Apple服务器: 选择Apple ID登录(可选隐藏邮箱) Apple服务器-->>App: 返回用户唯一标识(identityToken) App->>你的服务器: 上报identityToken+设备信息 你的服务器->>Apple服务器: 验证identityToken有效性 Apple服务器-->>你的服务器: 返回验证结果(包含userIdentifier) 你的服务器->>数据库: 绑定userIdentifier到订阅计划 你的服务器-->>App: 返回订阅成功 App->>用户: 解锁会员功能 loop 跨设备同步 用户->>新设备: 使用同一Apple ID登录 新设备->>你的服务器: 请求订阅状态(userIdentifier) 你的服务器-->>新设备: 返回有效订阅 新设备->>用户: 自动恢复会员 end

🛠 分步技术实现

1. 用户登录阶段

// 1. 集成Sign in with Apple按钮
import AuthenticationServices

let button = ASAuthorizationAppleIDButton()
button.addTarget(self, action: #selector(handleAppleID), for: .touchUpInside)

// 2. 处理登录回调
@objc func handleAppleID() {
    let request = ASAuthorizationAppleIDProvider().createRequest()
    request.requestedScopes = [.email] // 可选获取邮箱
    
    let controller = ASAuthorizationController(authorizationRequests: [request])
    controller.delegate = self
    controller.performRequests()
}

// 3. 获取用户唯一标识
func authorizationController(controller: ASAuthorizationController, 
                           didCompleteWithAuthorization authorization: ASAauthorization) {
    guard let credential = authorization.credential as? ASAuthorizationAppleIDCredential,
          let identityToken = credential.identityToken else { return }
    
    let userIdentifier = credential.user // 永久唯一标识
    sendToServer(identityToken: String(data: identityToken, encoding: .utf8)!)
}

2. 服务器验证逻辑

# 验证Apple身份令牌(Python示例)
def verify_apple_token(identity_token):
    import jwt
    from apple.auth import verify_apple_id_token
    
    # 1. 验证签名(需苹果公钥)
    claims = verify_apple_id_token(identity_token, audience="com.your.bundleid")
    
    # 2. 提取关键信息
    return {
        "user_id": claims["sub"],  # 唯一不变标识
        "email": claims.get("email", ""),
        "is_private_email": claims.get("email_verified", False)
    }

3. 订阅绑定与恢复

// 订阅购买成功时绑定
func paymentQueue(_ queue: SKPaymentQueue, 
                 updatedTransactions transactions: [SKPaymentTransaction]) {
    for tx in transactions {
        if tx.transactionState == .purchased {
            let receipt = getReceiptData()
            server.linkSubscription(
                userId: currentAppleUserId, 
                receipt: receipt
            )
        }
    }
}

// 检查订阅状态
func checkSubscription() {
    server.getSubscriptionStatus(userId: currentAppleUserId) { isValid in
        DispatchQueue.main.async {
            self.isPremium = isValid
        }
    }
}

📌 必须实现的细节

  1. 双重验证

    • 每次启动App时检查ASAuthorizationAppleIDProvider().getCredentialState
    func checkAppleIDStatus() {
        ASAuthorizationAppleIDProvider().getCredentialState(forUserID: userId) { state, error in
            if state == .revoked {
                // 用户已取消Apple ID授权
                server.revokeSubscription(userId: userId)
            }
        }
    }
    
  2. 隐私合规提示
    Info.plist中添加:

    <key>ASAuthorizationAppleIDProvider</key>
    <string>用于恢复您的会员权益</string>
    
  3. 跨设备同步流程图解

    graph LR A[设备A登录] -->|userIdentifier:123| B[你的服务器] B --> C[(数据库记录)] D[设备B登录] -->|同userIdentifier:123| B B -->|查询记录| C --> E[自动恢复订阅]

⚖️ 法律与审核要求

  1. 必须允许用户
    • 随时在iOS设置中取消Apple ID授权
    • 通过Apple ID恢复已购订阅
  2. 禁止行为
    • 要求额外注册密码账户
    • 限制同一Apple ID的设备数量(除非明确告知)

💡 体验优化建议

  1. 智能恢复提示

    func showRestoreTip() {
        if isFirstLaunch && !hasLocalSubscription {
            let alert = UIAlertController(
                title: "检测到Apple ID历史订阅",
                message: "要恢复之前的会员权益吗?",
                preferredStyle: .alert
            )
            alert.addAction(UIAlertAction(title: "恢复", style: .default) { _ in
                self.restorePurchase()
            })
            present(alert, animated: true)
        }
    }
    
  2. 多设备管理后台
    提供web页面让用户查看所有登录设备:
    https://yourdomain.com/apple-devices?user_id=123


这种方案既符合苹果要求,又能实现90%+的跨设备恢复率,且开发成本可控。

posted @ 2025-07-12 13:35  CH520  阅读(23)  评论(0)    收藏  举报