【PHP】苹果登录(sign in with apple)后端验证

第一种方法:验证identityToken

APP端登录成功后,会拿到一个identityToken的字段,里面的值是一个JWT,以.符号分隔,分为header、payload、signature三部分,类似长这样:

xxxx.yyyy.zzzz

APP需要把这个identityToken传给后端,后端进行验证。JWT里的signature部分是苹果使用私钥对其进行的签名,要验证这个签名,需要先获得苹果的公钥,而公钥可以通过JWKS(JSON Web Key Set)来转换获得。获取JWKS的接口是https://appleid.apple.com/auth/keys
在这里插入图片描述
接口返回的内容如上图,可以看到目前苹果有三个JWK(后面可能会随时变更,因此不能写死在服务端,必须通过接口获取!)。然后我们需要用到一个名为php-jwt的第三方库,使用composer命令安装:

composer require firebase/php-jwt

安装完后可以使用这个库来验证JWT签名和获取payload里的信息了,代码如下:

require_once(__DIR__ . "/vendor/autoload.php");

use Firebase\JWT\JWK;
use Firebase\JWT\JWT;

// APP登录成功后获得的identityToken
$identityToken = 'xxxx.yyyy.zzzz';

// 调用苹果接口获取JWKS
$apiResponse = file_get_contents('https://appleid.apple.com/auth/keys');
$jwkSet = json_decode($apiResponse, true);
if (!is_array($jwkSet)) {
    exit("Get JWK failed");
}

// 将JWKS转换为公钥
try {
    $pubKeys = JWk::parseKeySet($jwkSet);
} catch (\Exception $e) {
    exit("Parse key set failed:" . $e->getMessage());
}

// 使用公钥对JWT进行检验
try {
    $payload = JWT::decode($identityToken, $pubKeys, ['RS256']);
} catch (\Exception $e) {
    exit("Decode JWT failed:" . $e->getMessage());
}

// 若检验通过,会得到JWT里的payload信息
echo(json_encode($payload));

下图是payload里包含的信息例子:
在这里插入图片描述

获得payload信息后,还需要检查以下字段,确保:

  • iss的值等于https://appleid.apple.com
  • exp是JWT的过期时间,当前时间不能大于exp,也就是不能过期
  • aud的值等于你的应用的APP ID

全部通过后,就可以使用sub字段(用户的苹果账号ID)和email字段(用户的邮箱地址)完成后面的登录逻辑啦。

第二种方法:验证authorizationCode

APP端登录成功后,除了会拿到identityToken字段外,还可以拿到一个authorizationCode字段,下面介绍验证authorizationCode的方法。
验证authorizationCode需要有p8格式的私钥文件、私钥ID(Key ID)、Team ID这三样东西,私钥文件可以在苹果开发者后台下载,Key ID和Team ID也同样,见下图:
在这里插入图片描述
在这里插入图片描述

下载p8格式私钥后,使用下面命令转换为pem格式:

openssl pkcs8 -nocrypt -in AuthKey.p8 -out AuthKey.pem

最后通过苹果提供的接口来验证:

require_once(__DIR__ . "/vendor/autoload.php");

use Firebase\JWT\JWK;
use Firebase\JWT\JWT;

$clientId = ''; // APP的BUNDLE_ID
$authCode = ''; // APP登录成功后获得的authorizationCode
$teamId = ''; // Team ID
$keyId = ''; // Key ID
$privateKeyFilePath = "/path/to/AuthKey.pem"; // pem格式私钥文件的路径

// 使用私钥来生成client_secret
$privateKey = openssl_pkey_get_private("file://$privateKeyFilePath");
if (!$privateKey) {
    exit("Get private key failed");
}
$payload = [
    'iss' => $teamId,
    'iat' => time(),
    'exp' => time() + 86400,
    'aud' => 'https://appleid.apple.com',
    'sub' => $clientId,
];
$clientSecret = JWT::encode($payload, $privateKey, 'ES256', $keyId);

// 调用苹果接口验证authorizationCode
$postParams = [
    'client_id' => $clientId,
    'client_secret' => $clientSecret,
    'code' => $authCode,
    'grant_type' => 'authorization_code',
];

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => 'https://appleid.apple.com/auth/token',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HEADER => false,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => http_build_query($postParams),
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

var_dump($httpCode, $response);

若验证成功,苹果会返回200 HTTP状态码,并且有返回一个id_token字段,里面是一个包含用户信息的JWT,base64decode后再json_decode,就可以获得用户信息。

参考文章:
https://sarunw.com/posts/sign-in-with-apple-3/#how-to-verify-the-token
https://sarunw.com/posts/sign-in-with-apple-4/#create-a-sign-in-with-apple-private-key

Unity3D是一款流行的跨平台游戏开发引擎,支持多种移动平台和操作系统。最近,苹果推出了“Sign in with Apple”功能,该功能允许用户使用其Apple ID来登录第三方应用程序。 要在Unity3D中接入“Sign in with Apple”功能,需要遵循以下步骤: 1. 首先,确保你的Unity3D版本是最新的,以便能够支持最新的API和功能。 2. 在苹果开发者平台上创建一个新的App ID,并将其与你的Unity3D项目关联。确保在App ID设置中启用“Sign in with Apple”功能。 3. 在Unity3D中,编写代码以实现与苹果登录服务通信的逻辑。你需要使用Unity内置的网络API,通过发送HTTP请求和接收回复来实现与苹果服务器的通信。 4. 在Unity3D项目中创建一个用户界面,允许用户点击“Sign in with Apple”按钮。当用户点击这个按钮时,你的代码将向苹果服务器发送请求,获取用户的验证凭证。 5. 将从苹果服务器接收到的验证凭证与你的后端服务器通信。你的后端服务器需要验证这个凭证的有效性,并通过向苹果服务器发送请求获得用户的基本信息。 6. 在Unity3D中使用这些用户信息,例如显示用户的用户名、头像等。 需要注意的是,为了保护用户的隐私,苹果有一些要求和限制,开发人员需要遵守这些规定,例如要求提供“其他登录选项”以及对于用户与苹果登录服务的数据处理等。 总结:要在Unity3D中接入“Sign in with Apple”功能,你需要使用最新版本的Unity3D、遵循苹果开发者平台的规定、实现与苹果服务器的通信逻辑、创建用户界面、验证凭证、获取用户信息,并遵守苹果的隐私规定。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值