11 Replies
      Latest reply on Sep 13, 2019 1:29 AM by jerome2710
      jerome2710 Level 1 Level 1 (0 points)

        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?