ios Sign In With Apple PHP服務器驗證問題

Sign In With Apple服務器登錄驗證有很多問題,官方文檔寫的也不清不楚,網上資料不算多。
一、驗證identityToken有效性和正確性
根據官方文檔說明,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.蘋果後臺創建一個密鑰,用於獲取我們的 client_secret,這也是從 Apple 發出令牌請求所必需的。
(1) 進入 Certificates, Identifiers & Profiles > Keys,然後單擊 Keys 旁邊左上角的 + 號。
(2)提供密鑰名稱並確保勾選 Sign In with Apple。在這裏,我們還必須單擊 Configure。在接下來出現的Configure Key 面板中,選擇我們之前在 Choose a Primary App ID 下使用的 App ID,然後單擊“保存”。
(3) 單擊 Continue,然後在下一頁中驗證詳細信息並單擊 Register。
(4)下載密鑰並將其保存在安全的地方,因爲您永遠無法再次下載密鑰。下載密鑰後單擊 Done。
(5)保存key id和獲取開發者賬號的TeamID,後面需要使用這兩個值。
在這裏插入圖片描述
在這裏插入圖片描述
2.生成client_secret,需要使用jwt庫,規定生成的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官網解析看看結果
4.生成和刷新token
(1)請求url爲POST https://appleid.apple.com/auth/token
(2)生成令牌我們需要傳以下幾個參數
grant_type:'authorization_code’爲獲取令牌
client_id:client_id
redirect_uri:redirect_uri
code:上一步獲取到的授權碼,code
client_secret:一個生成的JWT,如果不瞭解可自行查閱有關JWT的知識
(3)刷新令牌我們需要傳以下參數
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.響應結果
(1)生成token響應結果:
{“access_token”:“xxxxxx”,“token_type”:“Bearer”,“expires_in”:3600,“refresh_token”:“xxxxxx”,“id_token”:“xxxxxxx”},其中id_token是一個JWT格式,所以需要再次解析。
(2)刷新token響應結果:
{“access_token”:“xxxxxx”,“token_type”:“Bearer”,“expires_in”:3600}
注意:根據官方文檔說明“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 從登陸到服務器驗證
(3)Sign in with Apple NODE,web端接入蘋果第三方登錄
(4)關於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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章