yanlongli / php-apple-signin
Verify Sign In with Apple identity tokens (JWT) in PHP: Apple JWKS/RS256, audience/nonce validation and ES256 client_secret generation. 苹果登录/苹果登陆 PHP SDK。
Requires
- php: ^8.0
- ext-json: *
- ext-openssl: *
- firebase/php-jwt: ^7.0
- guzzlehttp/guzzle: ^7.8 || ^8.0
Requires (Dev)
- phpunit/phpunit: ^10.5 || ^11.0
Suggests
- psr/simple-cache: Cache Apple public keys (^1.0 || ^2.0 || ^3.0) to avoid fetching them on every request.
Provides
None
Conflicts
None
Replaces
README
Server-side PHP SDK for Sign In with Apple (通过 Apple 登录 / 苹果登录 / 苹果登陆). Verify Apple identity tokens (JWT) from iOS, macOS and the web using Apple's public JWKS, and generate the ES256 client_secret for the token and revoke REST endpoints.
PHP library to verify and parse Sign In with Apple identity tokens server side, following Apple's current REST API guidance (JWKS/RS256 signature verification, issuer/audience/nonce/expiry checks), and to generate the ES256 client_secret needed by the server-to-server endpoints.
PHP 服务端验证并解析「通过 Apple 登录」(苹果登录 / 苹果登陆)身份令牌(JWT)。支持从 iOS、macOS 及网页端获取的 Apple identity token(
ASAuthorizationAppleIDCredential.identityToken/id_token),通过 Apple 官方 JWKS 公钥完成 RS256 签名验证,并严格按苹果最新文档校验签发者iss、受众aud(Bundle ID / Services ID)、nonce与过期时间;同时提供/auth/token、/auth/revoke等服务端接口所需的 ES256client_secret生成器。可直接用于 Laravel、Symfony、Hyperf 等框架。
Parity replacement of the unmaintained griffinledingham/php-apple-signin(已停止维护的苹果登录库的替代实现).
Features / 功能特性
- Verify Apple identity token JWT signature against
https://appleid.apple.com/auth/keysJWKS (RS256,kidmatching) - Enforce Apple's recommended claims:
iss,aud(client ID),exp/iat/nbfand anti-replaynonce - Typed access to
sub(user),email,email_verified,is_private_email,real_user_status,transfer_sub - PSR-16 cache and injectable Guzzle HTTP client for public keys (Guzzle 7 & 8)
- Generate ES256
client_secretfrom your.p8key, capped at Apple's 6-month limit - Framework agnostic: plain PHP, Laravel, Symfony, Hyperf, ...
- PHP 8+ with full static types and a PHPUnit test suite
基于官方 JWKS 验证 JWT 签名;校验 iss/aud/nonce/exp;类型化读取用户标识、邮箱(含私有中继邮箱)、真实用户状态等;支持 PSR-16 缓存公钥、自定义 Guzzle;生成 ES256 client_secret;框架无关,原生 PHP / Laravel / Symfony / Hyperf 均可用。
Requirements / 环境要求
- PHP
^8.0withext-jsonandext-openssl firebase/php-jwt^7.0(v6 is not supported: CVE-2025-45769 affects all releases below v7)guzzlehttp/guzzle^7.8 || ^8.0
Installation / 安装
composer require yanlongli/php-apple-signin
Verify an identity token / 验证身份令牌
use AppleSignIn\AppleSignInDecoder; use AppleSignIn\ApplePublicKeyProvider; use AppleSignIn\Exception\InvalidTokenException; // credential.identityToken (iOS) or the "id_token" field (web) $identityToken = $_POST['identity_token'] ?? ''; // App bundle ID (native) or Services ID (web) — enables the "aud" check $clientId = 'com.example.app'; $decoder = new AppleSignInDecoder(new ApplePublicKeyProvider()); try { // Third argument: expected nonce, when your auth request used one $token = $decoder->decode($identityToken, $clientId /* , $nonce */); } catch (InvalidTokenException $e) { http_response_code(401); exit($e->getMessage()); } $userIdentifier = $token->getUserIdentifier(); // "sub" === credential.user $email = $token->getEmail(); $emailVerified = $token->isEmailVerified(); $privateEmail = $token->isPrivateEmail(); if (!$token->verifyUser($clientProvidedUser)) { // credential.user mismatch }
The decoder performs every check recommended by Apple:
- RS256 signature against the live JWKS at
https://appleid.apple.com/auth/keys(kidmatched). iss === https://appleid.apple.com,exp/iat/nbf(120 s clock leeway by default).audequals your client ID and, when supplied,noncematches the session nonce.
解码器完整执行苹果要求的校验:基于 Apple JWKS 的 RS256 签名验证、签发者/过期时间校验、
aud客户端 ID 校验以及nonce防重放校验。
Available claim getters / Claim 读取方法
| Method | Claim |
|---|---|
getIssuer() |
iss |
getAudience() |
aud |
getUserIdentifier() / getUser() |
sub |
getEmail() |
email |
isEmailVerified() |
email_verified (bool or "true") |
isPrivateEmail() |
is_private_email |
getNonce() |
nonce |
isNonceSupported() |
nonce_supported |
getRealUserStatus() |
real_user_status |
getTransferSub() |
transfer_sub |
getExpiresAt() / getIssuedAt() / getNotBefore() |
exp / iat / nbf |
getClaim($name) / getClaims() |
raw access |
Caching Apple public keys / 缓存 Apple 公钥
Apple keys rarely rotate and should be cached. Pass any PSR-16 cache:
use AppleSignIn\ApplePublicKeyProvider; $provider = new ApplePublicKeyProvider($guzzleClient, $psr16Cache, ttl: 3600); $decoder = new AppleSignInDecoder($provider);
A pre-fetched JWKS (JSON string, array, or an already parsed Key map) can be
supplied through AppleSignIn\StaticPublicKeyProvider.
Generate a client_secret / 生成 client_secret
For the /auth/token and /auth/revoke endpoints, sign a JWT with the ES256
key (AuthKey_XXXXXXXXXX.p8) from Certificates, Identifiers & Profiles:
use AppleSignIn\ClientSecretGenerator; $clientSecret = ClientSecretGenerator::generate( teamId: 'TEAM1234AB', clientId: 'com.example.app', keyId: 'KEY1234567', privateKey: file_get_contents('/path/to/AuthKey_KEY1234567.p8'), );
The private key may be a PEM string, the raw key body, or a .p8 path. The
TTL is capped at Apple's 6-month limit (ClientSecretGenerator::MAX_TTL).
Migration from v1/v2 / 从旧版本迁移
The legacy static API still works and is backed by the new implementation:
use AppleSignIn\ASDecoder; $payload = ASDecoder::getAppleSignInPayload($identityToken); $payload->getEmail(); $payload->getUser(); $payload->verifyUser($clientUser);
It is deprecated: prefer AppleSignInDecoder (audience/nonce enforcement and
proper exceptions).
Testing / 测试
composer test
FAQ / 常见问题
See doc/faq.md.
Search terms / 搜索关键词
Sign In with Apple PHP, Apple ID login PHP, Apple identity token verification, Apple JWT JWKS RS256 validation PHP, firebase/php-jwt Apple keys, ES256 client_secret generator, ASAuthorizationAppleIDCredential server validation, iOS 苹果登录 PHP SDK, 苹果账号登陆服务端验证, 苹果授权登录 token 校验, 替代 griffinledingham/php-apple-signin.
Changelog
v3.0
- Requires PHP 8;
firebase/php-jwt^7.0,guzzlehttp/guzzle^7.8 || ^8.0. - New
AppleSignInDecoderwith strict issuer/audience/nonce/expiry verification and typedIdentityTokenclaims. - PSR-16 caching and injectable Guzzle client via
ApplePublicKeyProvider. - New
ClientSecretGeneratorfor ES256 client secrets. - Dedicated
AppleSignInException/InvalidTokenException. - PHPUnit test suite.
v2.0
Simplified decoding on top of firebase/php-jwt v6.
License
BSD-3-Clause