美文网首页
ios Sign In With Apple PHP服务器验证问

ios Sign In With Apple PHP服务器验证问

作者: 淡忘LQX | 来源:发表于2020-07-13 11:08 被阅读0次

    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

    相关文章

      网友评论

          本文标题:ios Sign In With Apple PHP服务器验证问

          本文链接:https://www.haomeiwen.com/subject/hchacktx.html