【发布时间】:2021-09-13 01:20:31
【问题描述】:
我有一个关于与苹果更准确地签名的问题,如何在登录后在 php 中创建 jw 令牌,这就是我所做的:
$pem_content =
"-----BEGIN PRIVATE KEY-----".
"XXXX".
"-----END PRIVATE KEY-----";
$header = json_encode(array(
'kid' => $keyId,
'alg' => 'ES256'
));
$decodedTokenData = json_decode(base64_decode(str_replace('_', '/', str_replace('-','+',explode('.', $_POST['id_token'])[1]))),true);
$payload = json_encode(array(
'iss' => $teamid,
'iat' => time(),
'exp' => time() + 86400*180,
'aud' => $decodedTokenData['aud'],
'sub' => $decodedTokenData['sub'],
));
$base64UrlHeader = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($header));
$base64UrlPayload = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($payload));
$key = //I don't know how to use $pem_content here
$signature = hash_hmac('sha256', $base64UrlHeader . "." . $base64UrlPayload, $key, true);
$base64UrlSignature = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($signature));
$jwt = $base64UrlHeader . "." . $base64UrlPayload . "." . $base64UrlSignature;
为了测试我做的交易
curl -X POST https://appleid.apple.com/auth/token -d '{"client_id":$CLIENTID,"client_secret":$jwt,"code": $_POST['code'],"grant_type":"authorization_code","redirect_uri":$URL}'
但我明白了
{"error":"invalid_client"}
这里有两个限制:我必须只使用 php 并避免使用外部库
提前致谢
编辑我像这样生成 jwt:
$signature = '';
openssl_sign($base64UrlHeader . "." . $base64UrlPayload, $signature,openssl_get_privatekey($pem_content),'SHA256');
$signature = $this->signatureFromDER($signature, 256);
使用的函数来自这里https://github.com/firebase/php-jwt/blob/d2113d9b2e0e349796e72d2a63cf9319100382d2/src/JWT.php#L172
现在 curl 命令是
curl -X POST "https://appleid.apple.com/auth/token" -H 'content-type: application/x-www-form-urlencoded' -d"client_id=CLIENT_ID&client_secret=CLIENT_SECRET&code=CODE&grant_type=authorization_code&redireect_uri=https%3A%2F%2Fsite.com%2Findex.php"
但我仍然得到 invalid_client
编辑2: 我没有实现这个解决方案: Apple Sign In "invalid_client", signing JWT for authentication using PHP and openSSL
但我一直有 invalid_client 错误
EDIT3 即使使用https://github.com/firebase/php-jwt 我也会收到错误
【问题讨论】:
-
看看这里的实现:github.com/firebase/php-jwt/blob/…。跳出来的一件事是使用
openssl_sign代替ES256而不是hash_hmac。 -
哦,还有一件事可能会让您感到困惑,根据文档 (developer.apple.com/documentation/sign_in_with_apple/…),该 POST 到
https://appleid.apple.com/auth/token的正文应该是application/x-www-form-urlencoded类型。 -
感谢您的帮助 msbit,现在我做
$signature = ''; openssl_sign($base64UrlHeader . "." . $base64UrlPayload, $pem_content,'ES256'); $signature = $this->signatureFromDER($signature, 256);jwt 是有效的(我已经在 jwt.io 上测试过),但我仍然有一个 'invalid_client' -
错字,
openssl_sign($base64UrlHeader . "." . $base64UrlPayload, $signature,$pem_content,'ES256'); -
错字,
alg缺少尾引号。