【发布时间】:2020-01-07 09:08:54
【问题描述】:
我很难弄清楚如何使用 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。欲了解更多信息,请查看this open pull request。
【问题讨论】:
-
这可能有帮助吗? stackoverflow.com/a/57622747/2412335
-
@digijay 恐怕不会。我们的域已经过验证。
-
我确实假设您发送的代码无效。您如何检索从授权端点收到的代码?
-
当你有你形成的包含代码的重定向 url(所以基本上你的函数返回的内容),然后你可以在那个 url 上执行一个 get ($code = $_GET['code'];) 到提取代码。这可能是你现在正在做的事情,但由于上面没有提到,我想我会提到它。
-
@Axelle 登录后的重定向 URL 被称为来自 Apple 的 POST 请求,包含代码和状态。请查看第二个代码块,我从 $_POST 检索代码并将其用于我对 Apple 的令牌请求。
标签: php oauth-2.0 jwt apple-sign-in