最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

ios - Apple server notifications JWT Invalid Header - Stack Overflow

programmeradmin4浏览0评论

I am using the following code to implement apple server notifications, but it's giving me an error "Invalid JWT Header". I am using storekit2 to purchase subscriptions in the app and I'm using a node js backend to keep track of subscription updates. Can someone help?

When I debug further I get JWT verification failed: Error: Invalid JWT header: Missing kid

I think the issue is that apple has not enabled V2 and is still sending V1 payload because I don't see signedPayload in the response from apple. How can I get it to send V2?

const APPLE_JWKS_URL = ";;
const getApplePublicKey = async (kid) => {
    try {
        const response = await axios.get(APPLE_JWKS_URL);
        const keys = response.data.keys;
        const key = keys.find((k) => k.kid === kid);

        if (!key) {
            throw new Error("Matching key not found");
        }

        return jwksClient.certToPEM({
            kty: key.kty,
            n: key.n,
            e: key.e,
        });
    } catch (error) {
        console.error("Failed to fetch Apple's public key:", error);
        throw new Error("Could not get Apple public key");
    }
};

// Function to verify Apple's JWT signature
const verifyAppleJWT = async (token) => {
    try {
        const decodedHeader = jwt.decode(token, { complete: true });

        if (!decodedHeader || !decodedHeader.header.kid) {
            throw new Error("Invalid JWT header");
        }

        const publicKey = await getApplePublicKey(decodedHeader.header.kid);
        return jwt.verify(token, publicKey, { algorithms: ["RS256"] });
    } catch (error) {
        console.error("JWT verification failed:", error);
        return null;
    }
};

// Apple Server Notification Endpoint
router.post("/apple-server-notifications", async (req, res) => {
    try {
        const { signedPayload } = req.body;

        if (!signedPayload) {
            return res.status(400).json({ error: "Missing signedPayload" });
        }

        // Verify the JWT signature with Apple's public key
        const payload = await verifyAppleJWT(signedPayload);
        if (!payload) {
            return res.status(400).json({ error: "Invalid notification" });
        }

        console.log("Verified Notification:", JSON.stringify(payload, null, 2));

        // Extract relevant data
        const eventType = payload.notificationType;
        const originalTransactionId = payload.data.originalTransactionId;

        // Handle subscription events
        switch (eventType) {
            case "SUBSCRIBED":
            case "DID_RENEW":
                await updateSubscription(originalTransactionId, "active");
                break;
            case "EXPIRED":
                await updateSubscription(originalTransactionId, "expired");
                break;
            case "CANCEL":
                await updateSubscription(originalTransactionId, "canceled");
                break;
            case "DID_REVOKE":
                await updateSubscription(originalTransactionId, "revoked");
                break;
            default:
                console.log(`Unhandled event type: ${eventType}`);
        }
        res.status(200).json({ message: "Notification processed" });
    } catch (error) {
        console.error("Error handling notification:", error);
        res.status(500).json({ error: "Internal Server Error" });
    }
});
发布评论

评论列表(0)

  1. 暂无评论