2

My website supports Sign In with Apple.

In the configurations of this service, I have an endpoint here:

enter image description here

What I receive in this endpoint is a JSON like this:

"{"payload":"eyJraW...................NLnyA"}

However, I don't find absolutely anywhere how to decrypt/decode this payload...

The "Learn more" link sends me here: https://developer.apple.com/help/account/configure-app-capabilities/about-sign-in-with-apple

The page below this one is this: https://developer.apple.com/help/account/configure-app-capabilities/enabling-server-to-server-notifications

Nowhere I see how to interpret these messages...

Does anyone know what do I need to do to read these payloads?

Nuno
  • 3,082
  • 5
  • 38
  • 58
  • Can you provide the full payload? – Michael M. Feb 04 '23 at 00:29
  • 1
    @MichaelM. - unfortunately, I won't be able to do that, as at the moment I don't know if it can contain private/sensitive information. I'm looking for an answer about what others do to decode these notifications from Apple. Thank you very much. – Nuno Feb 04 '23 at 00:34
  • JWTs are an open standard, you verify it the way you verify any JWT from any provider. Your language likely has a library or package for this purpose. – user229044 Feb 04 '23 at 01:21

2 Answers2

2

It looks like the general procedure for Server-to-Server notifications are outlined here. This is what the docs have to say:

These notifications contain a cryptographically signed payload, in JSON Web Signature (JWS) format, signed by Apple’s private key. After your server receives a notification, examine the JWS payload and use the algorithm specified in the header’s alg parameter to validate the signature. For more information, see Fetch Apple’s public key for verifying token signature.

So, this payload is really just a JWT (verify/decode with the JWT library of your choice, there are many to choose from). Because anyone can access your endpoint, you need to verify that the token is really from Apple. Note: do not try to decode the JWT yourself. Because of security concerns, it is better to let a library do it for you.

After validating the token signature, your server performs work according to the type value in the events claim of the token. The notification payload object contains information about user-initiated account modification events.

The decoded JWT will contain something like this (example is from the docs):

{
    "iss": "https://appleid.apple.com",
    "aud": "com.mytest.app",
    "iat": 1508184845,
    "jti": "abede...67890",
    "events": {
        "type": "email-enabled",
        "sub": "820417.faa325acbc78e1be1668ba852d492d8a.0219",
        "email": "ep9ks2tnph@privaterelay.appleid.com",
        "is_private_email": "true"
        "event_time": 1508184845
    }
}

events.type has the event that happened (full list is here), and the rest of the token contains everything else you'll need.

Michael M.
  • 10,486
  • 9
  • 18
  • 34
  • Thanks! I really appreciate this answer. See - even though you did help me here, the links still don't have the **answer** to what I need to do. Like, what is the "header's alg parameter" ???? But looking at this: https://stackoverflow.com/q/74999288/267594 , I see that the payload is split in 3 bits (by a dot "."), and decoding base64 the first bit, it has the alg parameter there. Then I call that Apple endpoint, and do the rest. How am I supposed to know all this??? – Nuno Feb 04 '23 at 19:04
  • @Nuno Those three dots are just how [JWTs](https://jwt.io) are formatted. Don't try to base64-decode it yourself, it could lead to vulnerabilities. Use a library instead (there are many to choose from and one in almost every language, see [this list](https://jwt.io/libraries)). – Michael M. Feb 04 '23 at 19:08
  • The `alg` parameter is just part of the JWT standard header. It tells you what algorithm the JWT uses for cryptographic signing. You shouldn't need to use it though, because your JWT library should just give you the payload. – Michael M. Feb 04 '23 at 19:09
  • 1
    Ah ok! I appreciate that. I'll look into using a JWT library, so! I have heard about JWT many times, and I know it's to do with securely pass data, but I haven't closely worked with it so far. Time to learn at last thank you. – Nuno Feb 04 '23 at 19:10
  • I just posted an answer with what needs to be done, but I'll leave yours as Accepted. Thanks! – Nuno Feb 04 '23 at 19:38
0

@Michael M.'s answer helped me understanding that this payload is basically a JWT.

This is what we need to do (minimal example):

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

$json = json_decode(file_get_contents('php://input'));

$publicKeys = json_decode(file_get_contents('https://appleid.apple.com/auth/keys'), true);

$decodedPayload = JWT::decode($json->payload, JWK::parseKeySet($publicKeys));

var_dump($decodedPayload);
Nuno
  • 3,082
  • 5
  • 38
  • 58