Sign In With Apple服務(wù)器登錄驗證有很多問題钳踊,官方文檔寫的也不清不楚,網(wǎng)上資料不算多大莫。
一蛉腌、驗證identityToken有效性和正確性
根據(jù)官方文檔說明,identityToken是一個JWT算法格式只厘,要使用JWT這個庫去進行解析烙丛,解析完成后進行驗證:
(1)Verify the JWS E256 signature using the server’s public key
(2)Verify the nonce for the authentication
(3)Verify that the iss field contains https://appleid.apple.com
(4)Verify that the aud field is the developer’s client_id
(5)Verify that the time is earlier than the exp value of the token
具體驗證方法可以參考某個博客的一篇文章,我這邊驗證identityToken都是參考這篇博客
try {
$identityToken = $verifyArray['identityToken'];
$appleSignInPayload = ASDecoder::getAppleSignInPayload($identityToken);
$email = $appleSignInPayload->getEmail();
$user = $appleSignInPayload->getUser();
$userId = $verifyArray['user'];
$isValid = $appleSignInPayload->verifyUser($userId);
// print_r($isValid);
if (!$isValid){
if($errDesc ==''){
$errDesc = 'verify userId fail';
}
}
return $appleSignInPayload;
}catch (Exception $exception){
// print_r($exception->getMessage());
if($errDesc ==''){
$errDesc = $exception->getMessage();
}
return null;
}
二羔味、authorizationCode驗證河咽,生成和刷新token
主要是authorizationCode驗證,我很懷疑這個是web Sign In With Apple的時候才需要用到赋元。
具體接口文檔
1.蘋果后臺創(chuàng)建一個密鑰忘蟹,用于獲取我們的 client_secret,這也是從 Apple 發(fā)出令牌請求所必需的搁凸。
(1) 進入 Certificates, Identifiers & Profiles > Keys媚值,然后單擊 Keys 旁邊左上角的 + 號。
(2)提供密鑰名稱并確保勾選 Sign In with Apple护糖。在這里褥芒,我們還必須單擊 Configure。在接下來出現(xiàn)的Configure Key 面板中嫡良,選擇我們之前在 Choose a Primary App ID 下使用的 App ID锰扶,然后單擊“保存”献酗。
(3) 單擊 Continue,然后在下一頁中驗證詳細信息并單擊 Register坷牛。
(4)下載密鑰并將其保存在安全的地方罕偎,因為您永遠無法再次下載密鑰。下載密鑰后單擊 Done京闰。
(5)保存key id和獲取開發(fā)者賬號的TeamID锨亏,后面需要使用這兩個值。
2.生成client_secret忙干,需要使用jwt庫,規(guī)定生成的JWT最長期限為6個月浪藻,你可以手動生成 JWT捐迫,但是不能使用firebase/php-jwt這個庫,因為這個庫缺少支持ES256算法格式爱葵,如果使用最后請求https://appleid.apple.com/auth/token這個接口返回的都是"error":"invalid_client"施戴,所以使用composer require lcobucci/jwt這個庫,具體代碼如下:
$payload = array(
"iss" => "Your Team ID",
"aud" => "https://appleid.apple.com",
"iat" => time(),
"sub" => "Your App Bundle ID",
"exp" => time()+ 86400*180
);
$jwt_header = array(
'typ' => 'JWT',
'alg' => 'ES256',
'kid' => 'The Key ID of the private key',
);
$key_path = 'file://D:\apple\AuthKey_keyid.p8';
$signer = new Lcobucci\JWT\Signer\Ecdsa\Sha256();
$key = new Lcobucci\JWT\Signer\Key($key_path);
$builder = new Lcobucci\JWT\Builder();
$builder->sign($signer, $key);
foreach($jwt_header as $key => $value)
$builder->withHeader($key, $value);
foreach($payload as $key => $value)
$builder->withClaim($key, $value);
$jwt_token = $builder->getToken();
// print_r($authorizationCode);
$jwt = (string)$jwt_token;
3.生成jwt格式的client_secret后萌丈,可以拿去JWT官網(wǎng)解析看看結(jié)果
4.生成和刷新token
(1)請求url為POST https://appleid.apple.com/auth/token
(2)生成令牌我們需要傳以下幾個參數(shù)
grant_type:'authorization_code'為獲取令牌
client_id:client_id
redirect_uri:redirect_uri
code:上一步獲取到的授權(quán)碼赞哗,code
client_secret:一個生成的JWT,如果不了解可自行查閱有關(guān)JWT的知識
(3)刷新令牌我們需要傳以下參數(shù)
grant_type:'refresh_token'為刷新令牌
client_id:client_id
client_secret:client_secret,
refresh_token:上一步獲取到的id_token
具體代碼如下:
$appleConfig = array();
$appleConfig['client_id'] = 'Your App Bundle ID';
$appleConfig['client_secret'] = $jwt;
$appleConfig['code'] = $authorizationCode;
$appleConfig['grant_type'] = 'authorization_code';//authorization_code,refresh_token
$biliConfig['redirect_uri'] = 'https://example.org';
// $appleConfig['refresh_token'] = 'rb65c3869af18460fb456fdgfh8.0.nrquq.DWHUDo7YTmZG_wqewwq-w';
$szUrl = 'https://appleid.apple.com/auth/token';
$request = new HttpHelper();
$response = $request->post($szUrl, $appleConfig);
5.響應(yīng)結(jié)果
(1)生成token響應(yīng)結(jié)果:
{"access_token":"xxxxxx","token_type":"Bearer","expires_in":3600,"refresh_token":"xxxxxx","id_token":"xxxxxxx"}辆雾,其中id_token是一個JWT格式肪笋,所以需要再次解析。
(2)刷新token響應(yīng)結(jié)果:
{"access_token":"xxxxxx","token_type":"Bearer","expires_in":3600}
注意:根據(jù)官方文檔說明“You may verify the refresh token up to once a day to confirm that the user’s Apple ID on that device is still in good standing with Apple’s servers. Apple’s servers may throttle your call if you attempt to verify a user’s Apple ID more than once a day”度迂,說的刷新token一天最多刷新一次藤乙,多了可能會限制你的賬號,所以最終考慮不使用這個接口進行登錄驗證惭墓。
6.參考文檔
(1)Generate and validate tokens
(2)Sign In With Apple 從登陸到服務(wù)器驗證
(3)Sign in with Apple NODE坛梁,web端接入蘋果第三方登錄
(4)關(guān)于Sign in with Apple (Apple 登錄) PHP的后端驗證
(5)oauth2-apple
(6)what-the-heck-is-sign-in-with-apple
(7)sign-in-with-apple-example
(8)What are we supposed to do with the access_token
(9)Apple Sign-In: Custom Servers and an Expiry Conundrum
(10)快速配置 Sign In with Apple