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

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