PHP code example of binuka200 / apple-sign-in

1. Go to this page and download the library: Download binuka200/apple-sign-in library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

binuka200 / apple-sign-in example snippets


use SafeApple\SignIn\AppleIdentityTokenVerifier;
use SafeApple\SignIn\AppleJwksProvider;
use SafeApple\SignIn\AppleOAuthClient;
use SafeApple\SignIn\ClientSecretGenerator;
use SafeApple\SignIn\Support\FlockRefreshLock;

$jwks = new AppleJwksProvider(
    cache: $sharedPsr16Cache,
    refreshLock: new FlockRefreshLock('/run/lock/my-app-apple-jwks.lock'),
);

$verifier = new AppleIdentityTokenVerifier(
    $jwks,
    ['com.example.app', 'com.example.web'],
    leeway: 30,
);

$clientSecret = ClientSecretGenerator::fromKeyFile(
    teamId: $_ENV['APPLE_TEAM_ID'],
    clientId: $_ENV['APPLE_CLIENT_ID'],
    keyId: $_ENV['APPLE_KEY_ID'],
    privateKeyPath: $_ENV['APPLE_PRIVATE_KEY_PATH'],
);

$oauth = new AppleOAuthClient($_ENV['APPLE_CLIENT_ID'], $clientSecret);

use SafeApple\SignIn\AuthorizationUrlBuilder;
use SafeApple\SignIn\LoginChallenge;

$challenge = LoginChallenge::generate();
$_SESSION['apple_challenge'] = [
    'state' => $challenge->state,
    'nonce' => $challenge->nonce,
];

$authorization = new AuthorizationUrlBuilder(
    $_ENV['APPLE_CLIENT_ID'],
    'https://example.com/auth/apple/callback',
);

header('Location: '.$authorization->build($challenge));

use SafeApple\SignIn\AppleAuthorizationResponse;
use SafeApple\SignIn\LoginChallenge;

$stored = $_SESSION['apple_challenge'] ?? null;
unset($_SESSION['apple_challenge']);

if (!is_array($stored)) {
    throw new RuntimeException('Apple login session expired.');
}

$challenge = new LoginChallenge($stored['state'], $stored['nonce']);
$callback = AppleAuthorizationResponse::fromPost($_POST, $challenge);
$callbackIdentity = $verifier->verifyAuthorizationResponse(
    $callback->identityToken,
    $callback->code,
    $challenge->nonce,
);

$tokens = $oauth->exchangeAuthorizationCode(
    $callback->code,
    'https://example.com/auth/apple/callback',
);

$identity = $verifier->verify($tokens->identityToken, $challenge->nonce);
if (!hash_equals($callbackIdentity->subject, $identity->subject)) {
    throw new RuntimeException('Apple identities do not match.');
}

// Use this as the stable provider identity. Never use email as the key.
$appleSubject = $identity->subject;

// The callback `user` object is browser-posted and is not signed. This helper
// returns its email only when it matches the verified identity-token email.
$verifiedProfileEmail = $callback->user?->verifiedEmail($identity);

// Apple only supplies the name on the first authorization. Persist it now.
// It is user-controlled text: escape it for the eventual output context.
$firstName = $callback->user?->firstName;
$lastName = $callback->user?->lastName;

// Store refresh tokens encrypted at rest.
$refreshToken = $tokens->refreshToken;

$tokens = $oauth->refresh($encryptedRefreshTokenAfterDecryption);

// When the local account is deleted or disconnected:
$oauth->revoke($refreshToken, 'refresh_token');

use SafeApple\SignIn\AppleAccountEvent;
use SafeApple\SignIn\AppleNotificationVerifier;

$notifications = new AppleNotificationVerifier(
    $jwks,
    ['com.example.app', 'com.example.web'],
);

$event = $notifications->verify($_POST['payload']);

// Before returning success, insert the verified event into a durable inbox or
// queue under a UNIQUE constraint on jwtId. A worker can then retry processing
// locally and idempotently until the account change succeeds.
enqueueAppleEventOnce($event);

http_response_code(204);
bash
gh attestation verify apple-sign-in-php-<version>.tar.gz --repo binuka200/apple-sign-in-php
sha256sum -c apple-sign-in-php-<version>.tar.gz.sha256