Last active
September 3, 2024 09:44
-
-
Save ameen-sarsour/e14a1d5bae5b61080dfdd5b1430c3e10 to your computer and use it in GitHub Desktop.
this code to try php sign in,
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* This file to test apple sign in, | |
* Need to app information from Apple | |
* | |
* Team Id | |
* Client Id | |
* Key Id | |
* and Private key | |
* | |
* and from App need to use code | |
* | |
* Note: Some of this codde is taken from firebase JWT library, I just copy&paste to make | |
* this code runnable withouy any dependency | |
* | |
*/ | |
const TEAM_ID = 'XXXXXXXXXX'; | |
const CLIENT_ID = 'com.XXXXXXXX.App'; | |
const KEY_ID = 'XXXXXXXXXX'; | |
$key = <<<KEY | |
-----BEGIN PRIVATE KEY----- | |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | |
XXXXXXXX | |
-----END PRIVATE KEY----- | |
KEY; | |
$ecdsa_key = openssl_pkey_get_private($key); | |
$header = array('typ' => 'JWT', 'alg' => 'ES256'); | |
$header['kid'] = KEY_ID; | |
$payload = [ | |
'iss' => TEAM_ID, | |
'iat' => time(), | |
'exp' => time() + 86400*180, | |
'aud' => 'https://appleid.apple.com', | |
'sub' => CLIENT_ID, | |
]; | |
$segments = array(); | |
$segments[] = urlsafeB64Encode(json_encode($header)); | |
$segments[] = urlsafeB64Encode(json_encode($payload)); | |
$signing_input = \implode('.', $segments); | |
$signature = ''; | |
$success = \openssl_sign($signing_input, $signature, $key, 'SHA256'); | |
if (!$success) { | |
throw new DomainException("OpenSSL unable to sign data"); | |
} else { | |
if ($header['alg'] === 'ES256') { | |
$signature = signatureFromDER($signature, 256); | |
} | |
} | |
$segments[] = urlsafeB64Encode($signature); | |
$clientSecret = \implode('.', $segments); | |
$code = 'CODE GENERATED FROM APP'; | |
$curl = curl_init(); | |
$postData = [ | |
"client_id=CLIENT_ID", | |
"client_secret=$clientSecret", | |
"code=$code", | |
"grant_type=authorization_code" | |
]; | |
curl_setopt_array($curl, array( | |
CURLOPT_URL => "https://appleid.apple.com/auth/token", | |
CURLOPT_RETURNTRANSFER => true, | |
CURLOPT_ENCODING => "", | |
CURLOPT_MAXREDIRS => 10, | |
CURLOPT_TIMEOUT => 0, | |
CURLOPT_FOLLOWLOCATION => true, | |
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, | |
CURLOPT_CUSTOMREQUEST => "POST", | |
CURLOPT_POSTFIELDS => implode('&', $postData), | |
)); | |
$response = curl_exec($curl); | |
curl_close($curl); | |
echo $response; | |
function urlsafeB64Encode($input) | |
{ | |
return \str_replace('=', '', \strtr(\base64_encode($input), '+/', '-_')); | |
} | |
function signatureFromDER($der, $keySize) | |
{ | |
// OpenSSL returns the ECDSA signatures as a binary ASN.1 DER SEQUENCE | |
list($offset, $_) = readDER($der); | |
list($offset, $r) = readDER($der, $offset); | |
list($offset, $s) = readDER($der, $offset); | |
// Convert r-value and s-value from signed two's compliment to unsigned | |
// big-endian integers | |
$r = \ltrim($r, "\x00"); | |
$s = \ltrim($s, "\x00"); | |
// Pad out r and s so that they are $keySize bits long | |
$r = \str_pad($r, $keySize / 8, "\x00", STR_PAD_LEFT); | |
$s = \str_pad($s, $keySize / 8, "\x00", STR_PAD_LEFT); | |
return $r . $s; | |
} | |
function readDER($der, $offset = 0) | |
{ | |
$ASN1_BIT_STRING = 0x03; | |
$pos = $offset; | |
$size = \strlen($der); | |
$constructed = (\ord($der[$pos]) >> 5) & 0x01; | |
$type = \ord($der[$pos++]) & 0x1f; | |
// Length | |
$len = \ord($der[$pos++]); | |
if ($len & 0x80) { | |
$n = $len & 0x1f; | |
$len = 0; | |
while ($n-- && $pos < $size) { | |
$len = ($len << 8) | \ord($der[$pos++]); | |
} | |
} | |
// Value | |
if ($type == $ASN1_BIT_STRING) { | |
$pos++; // Skip the first contents octet (padding indicator) | |
$data = \substr($der, $pos, $len - 1); | |
$pos += $len - 1; | |
} elseif (!$constructed) { | |
$data = \substr($der, $pos, $len); | |
$pos += $len; | |
} else { | |
$data = null; | |
} | |
return array($pos, $data); | |
} |
I think on line 52 $key should be $ecdsa_key because its not used anywhere, right?
Yes, that's right.
https://sarunw.com/posts/sign-in-with-apple-3/
$key is constantly changing, you can't hardcode it, that's why this doesn't work.
Hi @ameen-sarsour
I am getting error {"error":"invalid_client"}
- and from App need to use code
Is this code generated from flutter appappleCredential.identityToken
I am getting error {"error":"invalid_client"}
me too invalid_client
if o create the client_id on ruby it works but client_id created on php doesnt works!
me too invalid_client . I am using this code and create client_secret but show this error
Client error:
POST https://appleid.apple.com/auth/token
resulted in a400 Bad Request
response: {"error":"invalid_client","email_verified":false}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It only worked to me once, and I created my application on the base of that and later Apple started throwing me an error,
invalid_grant
. I was positive that the error wasn't at my end but it has to be the issue on theauth_token
from the App. But I am not the App developer. App developer was only saying 1 thing, they have to send theauth_token
only, nothing else is to be at their end. We abandon this feature now. Added this feature from the App instead of the Server end.