I am having a hard time figuring out how to use the sign in with Apple. The documentation is terrible and failed responses leaves us clueless. The article of Aaron Parecki (https://developer.okta.com/blog/2019/06/04/what-the-heck-is-sign-in-with-apple) does help a little, but I seem stuck now.
At first, I generate a login URL with /auth/authorize like so:
$_SESSION['state'] = bin2hex(openssl_random_pseudo_bytes(16)); return 'https://appleid.apple.com/auth/authorize?' . http_build_query([ 'response_type' => 'code', 'response_mode' => 'form_post', 'client_id' => 'com.my.service.id', 'redirect_uri' => 'https://my.app/redirect'), 'state' => $_SESSION['state'], 'scope' => 'name email', ]);
After struggling with the domain verification and return URLs, this brings me to the Apple login page and returns to my redirect_uri after succesfull login. Then, I need to authorize the token which I execute using Guzzle:
$response = (new Client)->request('POST', 'https://appleid.apple.com/auth/token', [ RequestOptions::FORM_PARAMS => [ 'grant_type' => 'authorization_code', 'code' => $_POST['code'], 'redirect_uri' => 'https://my.app/redirect', 'client_id' => 'com.my.service.id', 'client_secret' => $this->getClientSecret(), ], RequestOptions::HEADERS => [ 'Accept' => 'application/json' ] ]); return json_decode($response, true);
The client secret is generated using Firebase php-jwt (https://github.com/firebase/php-jwt) and is valid through jwt.io:
$key = openssl_pkey_get_private('file://certificate.p8'); return JWT::encode([ 'iss' => 'APPLETEAMID', 'iat' => time(), 'exp' => time() + 3600, 'aud' => 'https://appleid.apple.com', 'sub' => 'com.my.service.id', ], $key, 'ES256', 'certificate-id');
However, executing the token request to Apple returns a 400 error with the message 'invalid_client'. I cannot figure out if my client-id/secret is wrong or the code from the redirect is invalid. Can someone point me in the right direction?