invalid_client for authorization_code

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?

Replies

Hi jerome2710,


To troubleshoot this, we will need your client id. Please can you raise a Radar with your team / app / signing-in Apple Id and approx timestamp of the error.


Please title the Radar with "Sign in with Apple" or AuthKit. Thanks

Thank you for your reply. With Radar I think you mean the Feedback Assistant? I just submitted an entry with ID FB7219694.

Hello, I'm having the same exact issue, did anyone reply to you already?

The data you provded all looks good but you mentioned that you are using Firebase php-jwt. From what we see at https://jwt.io Firebase does not seem to support the ES256 algorithm.


Also from: https://github.com/firebase/php-jwt/blob/master/src/JWT.php:

public static $supported_algs = array(

'HS256' => array('hash_hmac', 'SHA256'),

'HS512' => array('hash_hmac', 'SHA512'),

'HS384' => array('hash_hmac', 'SHA384'),

'RS256' => array('openssl', 'SHA256'),

'RS384' => array('openssl', 'SHA384'),

'RS512' => array('openssl', 'SHA512'),

);


Can you try with another PHP library that supports ES256.

Unfortunately, nothing yet.

Thank you, I was already aware of that. The library will throw an error and never reach the point of the `invalid_client` response from Apple. In order to use ES256 with the Firebase php-jwt library, I extend the class and override the array of supported methods:


namespace my\namespace;

class JWT extends \Firebase\JWT\JWT
{
    public static $supported_algs = [
        'ES256' => ['openssl', 'SHA256'],
        'HS256' => ['hash_hmac', 'SHA256'],
        'HS512' => ['hash_hmac', 'SHA512'],
        'HS384' => ['hash_hmac', 'SHA384'],
        'RS256' => ['openssl', 'SHA256'],
        'RS384' => ['openssl', 'SHA384'],
        'RS512' => ['openssl', 'SHA512'],
    ];
}

Hello,


I also hace this problem, i use the same library, i also override the array, but i always get Invalid Client.


I use the right client_id (com.***.***) since it's the same that i use for displaying Apple Sign In button with the aplleid.js file mentioned in "Configure your website for Apple Sign in"...


Can you explain and respond to us ??? Why we always get this error ???

How does extending the class and adding ES256 build support for ES256 algorithm in the underlying framework ?

You are getting this error because we use ES256 algorithm and the framework you are using does not support it.

The firebase/php-jwt library uses PHP's native `openssl_sign()` function to generate the signature. To my understanding, ES256 uses SHA256 as well, but places ES256 in the header of the signature.


Please note that the generated signature does get validated in the JWT.io debugger, so there seems nothing wrong with the signature itself.

That is incorrect and not the cause of the problem, the signature is valid.

Same issue for me also.. Did you find a solution jerome ?

I filed a similar issue in Feedback Assistant. I am using python and have tried pyjwt and jwcrypto to generate the client secret (both supporting ES256) but am still getting an invalid_client error. Can I get a more detail exception as what I am doing incorrectly?

Just wanted to add a note here that I was able to resolve my issue. The issue was not with the client secret but with the TTL for my secret which expired way too soon and the redirect URI set for getting an auth token not being whitelisted in Apple developer services dashboard for apple sign in.

It looks like I have very similar (or same) issue as you had. Could you please point me out what did you do to make redirect URI whitelisted in Apple developer services dashboard?