6

我的用例是,一旦用户登录到我的应用程序,当我从我的应用程序向我的自定义服务器进行端点调用时,我使用登录产生的 Oauth 令牌对调用者进行身份验证。例如,我以这种方式使用Google 登录。

此方法(例如,使用 Google 登录)有几个有用的属性:

  1. 更新的令牌会在客户端应用程序上自动创建。

  2. 我的自定义服务器可以使用 Google 的端点轻松验证令牌的有效性。

  3. 初始令牌验证可以在端点请求处理的早期进行 - 无需访问自定义服务器数据库(如https://github.com/IBM-Swift/Kitura-Credentials中的样式)。

我的问题是:鉴于我们被告知必须将 Apple 登录合并到我们的 iOS 应用程序中(如果我们提供通用登录设施),我如何使用我的自定义服务器进行端点身份验证?

我看到了两种选择,我都不太喜欢。

首先,我可以让我的客户端应用程序向我的服务器发送 Apple 登录 id_token 并忽略 exp(到期)字段。我可以定期(显然,每天不超过一次)重新生成 id_token并将其发送回我的客户。我不喜欢这个想法,既因为忽略了令牌的到期,也因为需要定期将令牌从服务器发送到客户端。(我的应用程序使用多个登录系统,这只会造成额外的困难)。

其次,我可以让我的客户向我的服务器发送一个 Apple 登录刷新令牌。当然,我的服务器需要最初生成该刷新令牌并将其发送回客户端。我比第一个想法更喜欢这个想法。我在自定义服务器中的初始令牌验证将需要访问其数据库以查找与此令牌匹配的。我通常不能使用 Apple 端点——因为,Apple 显然会再次限制这种验证。

此外,我不太喜欢我的自定义服务器最多只能每天检查一次令牌有效性的想法。如果用户撤销应用程序的凭据,我希望我的自定义服务器能够相对较快地停止代表用户操作。

想法?


2019 年 10 月 5 日——更新到上面的第一个替代方案。在实际使用https://developer.apple.com/documentation/signinwithapplerestapi/generate_and_validate_tokens进行刷新令牌验证时,我发现它实际上并没有生成更新的 id 令牌。它正在生成一个访问令牌(但 Apple 没有定义它的用途),并正在验证刷新令牌。因此,无法将更新的 id 令牌发送到客户端 iOS 应用程序。因此,使用第一种替代方法,不能使用 id 令牌的到期日期。

19 年 10 月 10 日——更新:我写了一篇关于这个主题的博客文章——https: //medium.com/@crspybits/apple-sign-in-custom-servers-and-an-expiry-conundrum- d1ad63223870

20 年 8 月 6 日--更新:关注博客文章以及可能的前进路径,来自 Apple 的待定详细信息:https ://medium.com/@crspybits/part-ii-apple-sign-in-custom-servers-and-一个到期的难题-b3e9735dc079

4

1 回答 1

2

WWDC 2020 中充分利用 Sign in with Apple 中,他们在 11:30 的演示文稿中介绍了服务器到服务器的通知,以使您的服务器能够实时监控用户帐户状态的变化。

到目前为止,这方面的细节很少。

----------------- 更新 (12/23/20) -----------------

我现在有这些服务器到服务器的通知在我的服务器的测试环境中工作。一些注意事项:

  1. 我决定在我的服务器上使用端点,以允许 Apple 向我的服务器发送这些 REST 端点请求。

  2. 我将其粘贴到 developer.apple.com > Account > Certificates, Identifiers & Profiles > Identifiers > Select your app identifier > 单击“Sign In with Apple”旁边的“Edit” > Server to Server Notification Endpoint

  3. 这个端点实际上是未经授权的。例如,它是由 Apple 制作的,没有 OAuth 凭据访问您的服务器。如何设置将取决于您的服务器。我有办法为未经授权的服务器设置新的端点/路由。

  4. 我将客户端和服务器的其他部分设置为允许使用 Apple 登录创建帐户。因此,使用其中一个帐户,我现在开始采取行动,导致 Apple 在我的服务器上调用他们的服务器到服务器通知端点。我想对苹果提出的端点请求的细节进行逆向工程,因为细节很少。这提供了一些关于如何导致通知事件发生的想法: How to revoke Sign in with Apple credentials for a specific app? 您可以撤销凭据,但启用和禁用电子邮件中继更容易(因为您可以重复执行此操作)。当然,要做到这一点,您必须首先使用私人/电子邮件中继登录 Apple。

  5. 接下来我学到了两件事:

a) 在您采取行动(例如,撤销电子邮件中继)后,大约 30 秒内会在您的服务器上访问服务器到服务器通知端点。我已将各种日志输出添加到我的服务器中,因此可以查看我的服务器日志并看到这种情况发生。

b) Apple 向您的服务器发出的端点请求具有包含以下格式的 JSON 的正文数据: {"payload" : "-- SNIP -- JWT"}

我正在使用以下 Swift 结构对其进行解码。

    struct ApplePayload: Decodable {
        let payload: String // JWT
    }
  1. 正如苹果在 WWDC 2020 视频 ( https://developer.apple.com/videos/play/wwdc2020/10173/ ) 中指出的那样,body 数据的主要内容是 JWT。上面,这是 JSON 中键“payload”的值。

  2. 下一步是解码这个 JWT。我只是猜测它会在 Apple Sign In 服务器端进程的其他部分使用与 JWT 相同的解码机制。具体来说,在解码客户端使用 Apple 登录传递给您的服务器的身份令牌(JWT)时。请参阅https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api/authenticating_users_with_sign_in_with_apple 我有一些代码可以做到这一点JWT 解码,所以我将其分解并放在一个共同的地方: https ://github.com/SyncServerII/AppleJWTDecoder.git 将其集成到我对 Apple 的服务器到服务器通知请求的服务器端处理中,我发现确实可以用这种方式解码这个 JWT。

  3. 另一个显而易见的方面是,Apple 在 WWDC 2020 视频中指出的结构在解码后并不是 100% 存在于 JWT 中的结构。具体来说,到目前为止,在我的测试中,至少该events字段不是数组,而是具有单个值。有关 Swift 结构,请参阅https://github.com/SyncServerII/AppleJWTDecoder/blob/main/Sources/AppleJWTDecoder/AppleSignInClaims.swift

我现在成功解析了 JWT。我服务器上的下一个主要步骤是实际利用服务器中的不同事件类型来采取行动。对我来说,这将涉及两个帐户(不是电子邮件)相关的操作:

用户决定停止在您的应用程序中使用他们的 Apple ID。并且应该被用户视为退出。例如,当用户决定断开您的应用程序与设置的连接时。(来自 https://developer.apple.com/videos/play/wwdc2020/10173/

也被认为是用户“删除他们的应用程序帐户”的请求(更广泛的上下文:“服务器到服务器通知端点使用 Apple 服务器登录到服务器通知允许您接收有关您的用户及其帐户的重要更新。为每个应用程序发送通知当用户更改邮件转发偏好、删除他们的应用程序帐户或永久删除他们的 Apple ID 时的组。每组应用程序可以有一个 URL,该 URL 必须是绝对的,并且包括方案、主机和路径。需要 TLS 1.2 或更高版本接收通知。了解更多信息。”)要查看这些文档,请访问:developer.apple.com > 帐户 > 证书、标识符和配置文件 > 标识符 > 选择您的应用标识符 > 单击“使用 Apple 登录”旁边的“编辑”>服务器到服务器通知端点

case consentRevoked = "consent-revoked"

    

用户已要求 Apple 删除其 Apple ID。用户标识符现在将不再有效。

case accountDelete = "account-delete"

我的计划是将这两个事件视为等效 - 并删除我服务器上的用户帐户。然后,我将不得不考虑如何将其传达给我的客户(iOS 应用程序)。它需要知道用户已经删除了他们的帐户。

于 2020-06-26T23:26:26.887 回答