我有一个使用应用内购买的 iOS 应用程序。
当订阅某些计划时,苹果会在我提供的 webhook 上发布请求
在服务器端我从苹果接收此数据:
{"signedPayload": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"}
我无法找到适当的后端文档来验证此有效负载。
有人可以给我提供一些示例或文档或一个非常好的nodejs库,可以让我轻松解码并从这个签名的令牌中获取有价值的信息
从令牌(例如您指定的令牌)收集有效负载的策略与密码学基础知识相冲突。首先,您可能已经注意到您的
signedPayload
(从现在起我将其称为“源”)是一个 Base64 编码的 JSON 对象。 解码数据的最简单方法是使用 Base64 解码器 使有效负载部分以纯文本形式可见。虽然这是一个完美工作的解决方案,并且通常用于大多数非关键应用程序,但它不会检查有效负载的完整性,也不会验证源是否由 Apple 签名,这允许黑暗角色伪造有效负载,以便他们可以包含任何数据。更安全的解决方案是执行完整的 JWT 验证。可以通过以下步骤来实现:
kid
(密钥 ID)的密钥,你问了 NodeJS,代码如下:
const jwt = require("jsonwebtoken");
const axios = require("axios");
const jwkToPem = require("jwk-to-pem");
const jwksUrl = "https://appleid.apple.com/auth/keys"
async function getPublicKey(kid) {
const res = (await axios.get(jwksUrl)).data.keys;
const appleKey = res.find(key => key.kid == kid);
return appleKey;
}
async function verifyJWT(signedPayload) {
try {
const header = jwt.decode(signedPayload, { complete: true }).header;
const publicKey = await getPublicKey(header.kid);
if (!publicKey) {
throw new Error(`No matching key found for kid: ${kid}`);
} else {
console.log("Found matching key:");
console.log(publicKey);
}
const pem = jwkToPem(publicKey)
const decoded = jwt.verify(signedPayload, pem, { algorithms: ['RS256'] });
return decoded;
} catch (err) {
console.error('Error verifying Apple JWT:', err);
throw err;
}
}
const signedPayload = "your signed payload here"
verifyJWT(signedPayload)
.then(decoded => {
console.log('Verified and Decoded Payload:', decoded);
})
.catch(err => {
console.error('Verification failed:', err);
});