7

我很难弄清楚如何使用 Apple 登录。文档很糟糕,失败的响应让我们一无所知。Aaron Parecki 的文章(https://developer.okta.com/blog/2019/06/04/what-the-heck-is-sign-in-with-apple)确实有点帮助,但我现在似乎卡住了.

首先,我使用 /auth/authorize 生成一个登录 URL,如下所示:

$_SESSION['state'] = bin2hex(openssl_random_pseudo_bytes(16));

return 'https://appleid.apple.com/auth/authorize?' . http_build_query([
  'response_type' => 'code',
  'response_mode' => 'form_post',
  'client_id' => 'com.my.service.id',
  'redirect_uri' => 'https://my.app/redirect'),
  'state' => $_SESSION['state'],
  'scope' => 'name email',
]);

在与域验证和返回 URL 斗争之后,这将我带到 Apple 登录页面并在成功登录后返回到我的 redirect_uri。然后,我需要授权我使用 Guzzle 执行的令牌:

$response = (new Client)->request('POST', 'https://appleid.apple.com/auth/token', [
  RequestOptions::FORM_PARAMS => [
    'grant_type' => 'authorization_code',
    'code' => $_POST['code'],
    'redirect_uri' => 'https://my.app/redirect',
    'client_id' => 'com.my.service.id',
    'client_secret' => $this->getClientSecret(),
  ],
  RequestOptions::HEADERS => [
    'Accept' => 'application/json'
  ]
]);

return json_decode($response, true);

客户端密码是使用 Firebase php-jwt ( https://github.com/firebase/php-jwt ) 生成的,通过 jwt.io 有效:

$key = openssl_pkey_get_private('file://certificate.p8');

return JWT::encode([
  'iss' => 'APPLETEAMID',
  'iat' => time(),
  'exp' => time() + 3600,
  'aud' => 'https://appleid.apple.com',
  'sub' => 'com.my.service.id',
], $key, 'ES256', 'certificate-id');

但是,向 Apple 执行令牌请求会返回 400 错误并显示消息“invalid_client”。我无法确定我的客户端 ID/密码是否错误,或者重定向的代码是否无效。有人可以指出我正确的方向吗?

编辑:请注意我重写了 JWT 类,允许使用 ES256。有关更多信息,请查看此开放拉取请求

4

1 回答 1

-4

根据您所说的以及Apple在其文档中所说的内容,我认为您将 AppleIdentity tokenClient Secret.

AppleIdentity TokenJWT唯一标识用户的令牌,是现有 OAuth 2.0 框架“之上”的安全层。

当您在授权服务器中注册/验证您的客户端时,根据RFC 6749 - OAuth 2.0 授权框架,您很可能会从授权服务器收到一个秘密,这是您的客户端的秘密(即,您的服务器的密码com.my.service.id)到用于从获取令牌到使用身份检索资源的每个请求。使用这client_id/client_secret对的建议方法是HTTP Basic Authentication方法,不鼓励使用 POST 参数。

授权服务器必须支持 HTTP Basic 身份验证方案,以对已获得客户端密码的客户端进行身份验证。

...

不推荐使用这两个参数在请求正文中包含客户端凭据,并且应仅限于无法直接使用 HTTP 基本身份验证方案(或其他基于密码的 HTTP 身份验证方案)的客户端。参数只能在请求正文中传输,不得包含在请求 URI 中。

您将以 JWT 令牌的形式收到用户的Identity Token令牌,并且您应该准确地提供该令牌并且不能被篡改,因为该令牌是由 Apple 自己发行的。但是,您可以检查有效负载(请参阅jwt.io 上的 JWT 介绍iat + exp)以了解Identity Token. Identity Token除非您为 Apple 的授权团队编码,否则不应生成。

最后,我不能强调要彻底阅读 OAuth 规范并记住这Identity Token是 Apple 向您发送用户 ID 的方式,但 client_id 和 client_secret 是 OAuth 规范中定义的。

于 2019-09-12T11:39:41.060 回答