I am trying to understand Sign in with Apple. I am assuming a situation where there is an app server, an ios app and the apple authentication provider. In the WWDC 2020 session "Get the most out of Sign in with Apple" Apple has this to say about the nonce value in the authorization request:
But as we mentioned before, the request also has some properties that can help make the authorization process more secure. These are nonce and state.
These properties will allow you to verify that the authorization and credential you get after executing a request are the ones you were expecting. Let's start by talking about what these properties are. The nonce is an opaque blob of data sent as a string in the request. It is important to generate one unique nonce every time you create a new request, as later on, you will be able to verify this value.
In order to do that, the nonce value will be returned to you embedded in the identityToken property of the authorization credential.
This will allow you to verify this value in your server, helping prevent replay attacks.
My understanding is: The app client creates an upredictable nonce for the authorization request sent to Apple's servers. If all goes well, Apple will return an identity token containing the same nonce. The client can check that the identity token contains the same nonce value that it included in the request, then go on sending that JWT to the application server which can use Apple's public key and the signature to make sure that the JWT is indeed signed by apple and be therefore sure that the user is who they claim to be.
But Apple says that
This will allow you to verify this value in your server, helping prevent replay attacks.
(Emphasis mine)
In the flow I described my application server would not know the nonce, so it would not be able to verify anything about it. Is the suggestion here that the client requests a nonce (and a session id) from the application server first before creating an authorization request. Then sends that nonce as part of the authorization request, and later sends the JWT with the included nonce and the session id to the application server? So that the application server can also verify that the nonce is indeed the same one assigned at the start of the session?
You could request a state and nonce from your server, but I would not because this is a possible attack vector.
It is better to generate the state and nonce in your app. These are then included in the authentication request.
Once your app receives the response from Apple, it can verify that the state matches the state that it is expecting.
You then send the identity token and the expected nonce value to your server. The server validates that the JWT was signed by Apple and contains the expected nonce.
As an example of the flow you could use: