<?php
session_start();

// Read this blog post for a full walkthrough of this code
// https://developer.okta.com/blog/2019/06/04/what-the-heck-is-sign-in-with-apple

// Apple's docs are here but are incomplete and incorrect in some places
// https://developer.apple.com/sign-in-with-apple/get-started/


// The client ID is the "Services ID" value that you get during setup
$client_id = '';

// The client secret is a ECDSA signed JWT using the key you get from the developer portal
// Generating the JWT:
// https://developer.apple.com/documentation/signinwithapplerestapi/generate_and_validate_tokens#3262048

// You can generate the secret from the Ruby code in this repository
$client_secret = '';

// Redirect URLs must be registered with Apple. You can register up to 10.
// Apple will throw an error with IP address URLs on the authorization screen,
// and will not let you add localhost in the developer portal.
$redirect_uri = 'https://example-app.com/redirect';




if(isset($_POST['code'])) {

  if($_SESSION['state'] != $_POST['state']) {
    die('Authorization server returned an invalid state parameter');
  }

  if(isset($_REQUEST['error'])) {
    die('Authorization server returned an error: '.htmlspecialchars($_REQUEST['error']));
  }

  // Token endpoint docs: 
  // https://developer.apple.com/documentation/signinwithapplerestapi/generate_and_validate_tokens

  $response = http('https://appleid.apple.com/auth/token', [
    'grant_type' => 'authorization_code',
    'code' => $_POST['code'],
    'redirect_uri' => $redirect_uri,
    'client_id' => $client_id,
    'client_secret' => $client_secret,
  ]);

  if(!isset($response->access_token)) {
    echo '<p>Error getting an access token:</p>';
    echo '<pre>'; print_r($response); echo '</pre>';
    echo '<p><a href="/">Start Over</a></p>';
    die();
  }

  echo '<h3>Access Token Response</h3>';
  echo '<pre>'; print_r($response); echo '</pre>';


  $claims = explode('.', $response->id_token)[1];
  $claims = json_decode(base64_decode($claims));

  echo '<pre>';
  print_r($claims);
  echo '</pre>';

  die();
}


// Show a link to log in

$_SESSION['state'] = bin2hex(random_bytes(5));

$authorize_url = 'https://appleid.apple.com/auth/authorize'.'?'.http_build_query([
  'response_type' => 'code',
  'response_mode' => 'form_post',
  'client_id' => $client_id,
  'redirect_uri' => $redirect_uri,
  'state' => $_SESSION['state'],
  'scope' => 'name email',
]);


echo '<div id="appleid-signin" data-color="black" data-border="true" data-type="sign in"><div style=" display: inline-flex; box-sizing: border-box; width: 100%; height: 100%; min-width: 200px; min-height: 32px; max-height: 64px; border-radius: 5px; background-color: black; color: white; border: .5px solid black;"> <a href="'.$authorize_url.'" style="display:block;width:100%"><svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="-4 -4 141.2412109375 32" fill="#fff"> <g transform="scale(0.8) translate(0, -7)"> <path d="M8.02 16.23c-.73 0-1.86-.83-3.05-.8-1.57.02-3.01.91-3.82 2.32-1.63 2.83-.42 7.01 1.17 9.31.78 1.12 1.7 2.38 2.92 2.34 1.17-.05 1.61-.76 3.03-.76 1.41 0 1.81.76 3.05.73 1.26-.02 2.06-1.14 2.83-2.27.89-1.3 1.26-2.56 1.28-2.63-.03-.01-2.45-.94-2.48-3.74-.02-2.34 1.91-3.46 2-3.51-1.1-1.61-2.79-1.79-3.38-1.83-1.54-.12-2.83.84-3.55.84zm2.6-2.36c.65-.78 1.08-1.87.96-2.95-.93.04-2.05.62-2.72 1.4-.6.69-1.12 1.8-.98 2.86 1.03.08 2.09-.53 2.74-1.31"></path> </g> <g transform="translate(15, 3.6)"> <path d="M0.79 10.75L0.79 10.75L2.03 10.75Q2.11 11.27 2.44 11.65Q2.78 12.02 3.32 12.23Q3.87 12.44 4.57 12.44L4.57 12.44Q5.23 12.44 5.75 12.22Q6.27 12.00 6.57 11.62Q6.87 11.24 6.87 10.75L6.87 10.75Q6.87 10.12 6.39 9.70Q5.91 9.28 4.89 9.03L4.89 9.03L3.63 8.70Q2.29 8.37 1.68 7.73Q1.07 7.10 1.07 6.04L1.07 6.04Q1.07 5.41 1.32 4.90Q1.57 4.38 2.03 4.01Q2.50 3.64 3.14 3.44Q3.78 3.23 4.56 3.23L4.56 3.23Q5.28 3.23 5.89 3.44Q6.49 3.64 6.95 4.00Q7.41 4.37 7.68 4.87Q7.95 5.37 7.99 5.96L7.99 5.96L6.75 5.96Q6.62 5.20 6.03 4.77Q5.44 4.35 4.52 4.35L4.52 4.35Q3.86 4.35 3.37 4.55Q2.88 4.76 2.61 5.13Q2.34 5.50 2.34 6.00L2.34 6.00Q2.34 6.58 2.78 6.95Q3.22 7.31 4.24 7.57L4.24 7.57L5.27 7.84Q6.29 8.09 6.92 8.46Q7.55 8.83 7.84 9.35Q8.13 9.87 8.13 10.60L8.13 10.60Q8.13 11.50 7.68 12.16Q7.23 12.83 6.41 13.20Q5.58 13.56 4.45 13.56L4.45 13.56Q3.40 13.56 2.60 13.21Q1.80 12.87 1.32 12.24Q0.85 11.61 0.79 10.75ZM11.23 13.33L10.06 13.33L10.06 5.96L11.23 5.96L11.23 13.33ZM10.64 4.54L10.64 4.54Q10.42 4.54 10.23 4.43Q10.04 4.32 9.93 4.13Q9.82 3.94 9.82 3.72L9.82 3.72Q9.82 3.49 9.93 3.31Q10.04 3.12 10.23 3.01Q10.42 2.90 10.64 2.90L10.64 2.90Q10.87 2.90 11.06 3.01Q11.25 3.12 11.35 3.31Q11.46 3.49 11.46 3.72L11.46 3.72Q11.46 3.94 11.35 4.13Q11.25 4.32 11.06 4.43Q10.87 4.54 10.64 4.54ZM16.45 12.18L16.45 12.18Q17.14 12.18 17.63 11.85Q18.12 11.53 18.38 10.93Q18.64 10.34 18.64 9.54L18.64 9.54Q18.64 8.74 18.38 8.14Q18.12 7.55 17.63 7.22Q17.14 6.89 16.45 6.89L16.45 6.89Q15.77 6.89 15.30 7.22Q14.82 7.55 14.57 8.14Q14.32 8.74 14.32 9.54L14.32 9.54Q14.32 10.34 14.57 10.93Q14.82 11.53 15.30 11.85Q15.77 12.18 16.45 12.18ZM16.51 16.16L16.51 16.16Q15.62 16.16 14.96 15.91Q14.29 15.66 13.90 15.21Q13.51 14.75 13.42 14.14L13.42 14.14L14.66 14.14Q14.76 14.59 15.24 14.86Q15.72 15.13 16.51 15.13L16.51 15.13Q17.50 15.13 18.06 14.67Q18.61 14.21 18.61 13.40L18.61 13.40L18.61 11.95L18.50 11.95Q18.16 12.56 17.55 12.89Q16.95 13.22 16.19 13.22L16.19 13.22Q15.24 13.22 14.55 12.76Q13.86 12.30 13.48 11.47Q13.10 10.64 13.10 9.54L13.10 9.54Q13.10 8.71 13.32 8.03Q13.54 7.35 13.94 6.86Q14.34 6.36 14.91 6.10Q15.48 5.83 16.19 5.83L16.19 5.83Q16.71 5.83 17.17 5.99Q17.63 6.15 17.99 6.44Q18.35 6.73 18.56 7.13L18.56 7.13L18.67 7.13L18.67 5.96L19.79 5.96L19.79 13.46Q19.79 14.29 19.39 14.89Q18.98 15.50 18.25 15.83Q17.51 16.16 16.51 16.16ZM23.18 13.33L22.00 13.33L22.00 5.96L23.13 5.96L23.13 7.12L23.24 7.12Q23.51 6.51 24.06 6.17Q24.60 5.83 25.45 5.83L25.45 5.83Q26.69 5.83 27.36 6.54Q28.03 7.25 28.03 8.56L28.03 8.56L28.03 13.33L26.85 13.33L26.85 8.85Q26.85 7.85 26.42 7.37Q26.00 6.89 25.12 6.89L25.12 6.89Q24.53 6.89 24.09 7.14Q23.66 7.39 23.42 7.86Q23.18 8.33 23.18 8.97L23.18 8.97L23.18 13.33ZM35.33 13.33L34.15 13.33L34.15 5.96L35.33 5.96L35.33 13.33ZM34.74 4.54L34.74 4.54Q34.51 4.54 34.33 4.43Q34.14 4.32 34.03 4.13Q33.92 3.94 33.92 3.72L33.92 3.72Q33.92 3.49 34.03 3.31Q34.14 3.12 34.33 3.01Q34.51 2.90 34.74 2.90L34.74 2.90Q34.97 2.90 35.15 3.01Q35.34 3.12 35.45 3.31Q35.56 3.49 35.56 3.72L35.56 3.72Q35.56 3.94 35.45 4.13Q35.34 4.32 35.15 4.43Q34.97 4.54 34.74 4.54ZM38.75 13.33L37.57 13.33L37.57 5.96L38.69 5.96L38.69 7.12L38.80 7.12Q39.07 6.51 39.62 6.17Q40.17 5.83 41.02 5.83L41.02 5.83Q42.26 5.83 42.93 6.54Q43.59 7.25 43.59 8.56L43.59 8.56L43.59 13.33L42.42 13.33L42.42 8.85Q42.42 7.85 41.99 7.37Q41.56 6.89 40.68 6.89L40.68 6.89Q40.09 6.89 39.66 7.14Q39.22 7.39 38.99 7.86Q38.75 8.33 38.75 8.97L38.75 8.97L38.75 13.33ZM57.78 5.96L58.96 5.96L56.90 13.33L55.70 13.33L54.05 7.63L53.94 7.63L52.30 13.33L51.11 13.33L49.05 5.96L50.24 5.96L51.69 11.85L51.80 11.85L53.44 5.96L54.57 5.96L56.22 11.85L56.33 11.85L57.78 5.96ZM61.74 13.33L60.56 13.33L60.56 5.96L61.74 5.96L61.74 13.33ZM61.15 4.54L61.15 4.54Q60.92 4.54 60.73 4.43Q60.55 4.32 60.44 4.13Q60.33 3.94 60.33 3.72L60.33 3.72Q60.33 3.49 60.44 3.31Q60.55 3.12 60.73 3.01Q60.92 2.90 61.15 2.90L61.15 2.90Q61.37 2.90 61.56 3.01Q61.75 3.12 61.86 3.31Q61.97 3.49 61.97 3.72L61.97 3.72Q61.97 3.94 61.86 4.13Q61.75 4.32 61.56 4.43Q61.37 4.54 61.15 4.54ZM64.47 5.96L64.47 4.05L65.65 4.05L65.65 5.96L67.29 5.96L67.29 6.95L65.65 6.95L65.65 11.12Q65.65 11.76 65.91 12.06Q66.17 12.35 66.74 12.35L66.74 12.35Q66.90 12.35 67.01 12.35Q67.12 12.34 67.29 12.33L67.29 12.33L67.29 13.32Q67.11 13.34 66.94 13.36Q66.77 13.38 66.60 13.38L66.60 13.38Q65.84 13.38 65.37 13.19Q64.90 12.99 64.69 12.55Q64.47 12.12 64.47 11.42L64.47 11.42L64.47 6.95L63.28 6.95L63.28 5.96L64.47 5.96ZM70.31 13.33L69.13 13.33L69.13 3.04L70.31 3.04L70.31 7.12L70.42 7.12Q70.69 6.51 71.26 6.17Q71.84 5.83 72.69 5.83L72.69 5.83Q73.47 5.83 74.04 6.15Q74.61 6.47 74.92 7.09Q75.23 7.70 75.23 8.56L75.23 8.56L75.23 13.33L74.05 13.33L74.05 8.85Q74.05 7.87 73.62 7.38Q73.19 6.89 72.35 6.89L72.35 6.89Q71.69 6.89 71.23 7.15Q70.78 7.41 70.54 7.88Q70.31 8.35 70.31 8.97L70.31 8.97L70.31 13.33ZM89.18 13.33L87.89 13.33L86.90 10.51L82.97 10.51L81.98 13.33L80.69 13.33L84.33 3.47L85.54 3.47L89.18 13.33ZM84.99 5.06L84.88 5.06L83.34 9.46L86.54 9.46L84.99 5.06ZM94.35 5.83L94.35 5.83Q95.29 5.83 95.98 6.30Q96.68 6.77 97.06 7.63Q97.45 8.49 97.45 9.65L97.45 9.65Q97.45 10.51 97.23 11.21Q97.01 11.92 96.60 12.42Q96.20 12.92 95.62 13.19Q95.05 13.46 94.35 13.46L94.35 13.46Q93.56 13.46 92.96 13.14Q92.35 12.81 92.05 12.22L92.05 12.22L91.94 12.22L91.94 15.79L90.76 15.79L90.76 5.96L91.88 5.96L91.88 7.19L91.99 7.19Q92.35 6.56 92.97 6.19Q93.60 5.83 94.35 5.83ZM94.07 12.40L94.07 12.40Q94.75 12.40 95.23 12.07Q95.71 11.74 95.97 11.13Q96.23 10.51 96.23 9.65L96.23 9.65Q96.23 8.78 95.97 8.17Q95.72 7.55 95.23 7.22Q94.75 6.89 94.08 6.89L94.08 6.89Q93.41 6.89 92.92 7.23Q92.44 7.56 92.17 8.18Q91.90 8.80 91.90 9.65L91.90 9.65Q91.90 10.49 92.17 11.10Q92.44 11.72 92.92 12.06Q93.41 12.40 94.07 12.40ZM102.88 5.83L102.88 5.83Q103.82 5.83 104.51 6.30Q105.21 6.77 105.59 7.63Q105.98 8.49 105.98 9.65L105.98 9.65Q105.98 10.51 105.76 11.21Q105.54 11.92 105.13 12.42Q104.73 12.92 104.16 13.19Q103.58 13.46 102.88 13.46L102.88 13.46Q102.09 13.46 101.49 13.14Q100.88 12.81 100.58 12.22L100.58 12.22L100.47 12.22L100.47 15.79L99.29 15.79L99.29 5.96L100.41 5.96L100.41 7.19L100.52 7.19Q100.88 6.56 101.50 6.19Q102.13 5.83 102.88 5.83ZM102.60 12.40L102.60 12.40Q103.28 12.40 103.76 12.07Q104.24 11.74 104.50 11.13Q104.76 10.51 104.76 9.65L104.76 9.65Q104.76 8.78 104.50 8.17Q104.25 7.55 103.77 7.22Q103.28 6.89 102.61 6.89L102.61 6.89Q101.94 6.89 101.46 7.23Q100.97 7.56 100.70 8.18Q100.43 8.80 100.43 9.65L100.43 9.65Q100.43 10.49 100.70 11.10Q100.97 11.72 101.45 12.06Q101.94 12.40 102.60 12.40ZM109.07 13.33L107.89 13.33L107.89 3.04L109.07 3.04L109.07 13.33ZM114.29 6.87L114.29 6.87Q113.70 6.87 113.25 7.14Q112.79 7.41 112.52 7.90Q112.25 8.38 112.21 9.04L112.21 9.04L116.27 9.04Q116.25 8.38 116.00 7.90Q115.75 7.41 115.32 7.14Q114.88 6.87 114.29 6.87ZM116.23 11.42L116.23 11.42L117.41 11.42Q117.24 12.05 116.81 12.51Q116.38 12.97 115.75 13.21Q115.11 13.46 114.30 13.46L114.30 13.46Q113.28 13.46 112.53 13.00Q111.79 12.53 111.38 11.67Q110.98 10.81 110.98 9.65L110.98 9.65Q110.98 8.78 111.21 8.08Q111.45 7.38 111.88 6.87Q112.32 6.37 112.93 6.10Q113.54 5.83 114.30 5.83L114.30 5.83Q115.30 5.83 116.02 6.28Q116.73 6.73 117.12 7.56Q117.50 8.39 117.50 9.54L117.50 9.54L117.50 9.99L112.21 9.99L112.21 10.04Q112.24 10.77 112.51 11.31Q112.77 11.84 113.24 12.13Q113.70 12.42 114.33 12.42L114.33 12.42Q115.04 12.42 115.52 12.16Q116.00 11.91 116.23 11.42Z"></path> </g> </svg></a> </div></div>';





function http($url, $params=false) {
  $ch = curl_init($url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  if($params)
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Accept: application/json',
    'User-Agent: curl', # Apple requires a user agent header at the token endpoint
  ]);
  $response = curl_exec($ch);
  return json_decode($response);
}

