Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Oauth2 Apple Laravel Package

patrickbussmann/oauth2-apple

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require patrickbussmann/oauth2-apple:^0.4.0
    

    Add the provider to your config/auth.php under providers:

    'apple' => [
        'client_id' => env('APPLE_CLIENT_ID'),
        'team_id' => env('APPLE_TEAM_ID'),
        'key_id' => env('APPLE_KEY_ID'),
        'private_key' => env('APPLE_PRIVATE_KEY'),
        'redirect' => env('APPLE_REDIRECT_URI'),
    ],
    
  2. Environment Variables Store sensitive keys in .env:

    APPLE_CLIENT_ID=your_client_id
    APPLE_TEAM_ID=your_team_id
    APPLE_KEY_ID=your_key_id
    APPLE_PRIVATE_KEY=-----BEGIN PRIVATE KEY-----\n...
    APPLE_REDIRECT_URI=http://your-app.com/auth/apple/callback
    
  3. First Use Case: Add Login Button Use the Socialite facade to generate an Apple login link:

    use Laravel\Socialite\Facades\Socialite;
    
    $appleAuthUrl = Socialite::driver('apple')->stateless()->redirect()->getTargetUrl();
    

    Render a button in your Blade view:

    <a href="{{ $appleAuthUrl }}" class="btn-apple">Sign in with Apple</a>
    

Implementation Patterns

Workflow: User Authentication

  1. Redirect to Apple

    return Socialite::driver('apple')->stateless()->redirect();
    
    • Use stateless() for SPF compliance (required for Apple).
  2. Handle Callback

    public function handleAppleCallback()
    {
        try {
            $user = Socialite::driver('apple')->stateless()->user();
            // Attach or create user in your system
            return redirect()->route('dashboard');
        } catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
            // Enhanced error handling with error_description
            \Log::error('Apple OAuth Error: ' . $e->getMessage() . ' | Description: ' . $e->getErrorDescription());
            return back()->with('error', 'Apple login failed. Please try again.');
        }
    }
    
  3. User Data Handling Extract key fields from the response:

    $email = $user->getEmail(); // May be null (privacy-preserving)
    $name = $user->getName();
    $userId = $user->getId(); // Unique Apple ID
    

Integration Tips

  • Fallback for Missing Email Apple may omit the email for privacy. Use a placeholder or prompt the user to provide it:

    $email = $user->getEmail() ?? 'apple_' . $user->getId() . '@user.example.com';
    
  • State Management For CSRF protection, pass a state parameter:

    $state = Str::random(40);
    session(['apple_state' => $state]);
    $appleAuthUrl = Socialite::driver('apple')->stateless()->with(['state' => $state])->redirect()->getTargetUrl();
    
  • Testing Use a mock provider for local testing. Note: PHP 8.3+ is now required for testing:

    Socialite::driver('apple')->shouldReceive('stateless')->andReturnSelf();
    Socialite::driver('apple')->shouldReceive('user')->andReturn((new MockUser())->setEmail('test@example.com'));
    

Gotchas and Tips

Pitfalls

  1. SPF Requirement

    • Apple requires stateless mode (stateless()). Omitting it will fail with:
      Error: Invalid client configuration. SPF must be enabled.
      
    • Fix: Always use Socialite::driver('apple')->stateless().
  2. Email Privacy

    • Apple may return null for email. Handle this gracefully:
      if (!$user->getEmail()) {
          // Prompt user to enter email or use a generated one.
      }
      
  3. Key Rotation

    • If your private key expires, update .env and clear cached configurations:
      php artisan config:clear
      
  4. Redirect URI Mismatch

    • Ensure APPLE_REDIRECT_URI matches exactly (including http/https) with your Apple Developer account settings. A mismatch throws:
      Error: Redirect URI mismatch.
      
  5. PHP Version Compatibility

    • Breaking Change: This release drops support for PHP ≤7.4. Ensure your environment uses PHP 8.3 or 8.5 for testing and production.

Debugging

  • Enhanced Error Handling The package now includes error_description in exception messages. Log errors for debugging:

    try {
        $user = Socialite::driver('apple')->stateless()->user();
    } catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
        \Log::debug('Apple OAuth Error Details:', [
            'message' => $e->getMessage(),
            'error_description' => $e->getErrorDescription(),
            'response' => $e->getResponseBody(),
        ]);
    }
    
  • Common Errors

    Error Message Solution
    invalid_client Verify APPLE_CLIENT_ID and APPLE_TEAM_ID in Apple Developer Console.
    invalid_request Check APPLE_REDIRECT_URI format.
    invalid_scope Ensure you’re requesting only email or name (Apple’s allowed scopes).
    Server Error: 500 (no details) Enable debug mode (APP_DEBUG=true) and check logs.
    `Error: [message] Description: [details]`

Extension Points

  1. Custom User Mapping Override the default user mapping in a service provider:

    public function boot()
    {
        Socialite::extend('apple', function ($app) {
            $config = $app['config']['services.apple'];
            return Socialite::buildProvider(
                AppleProvider::class,
                $config
            )->setUserFromResponseCallback(function ($response) {
                return new CustomAppleUser($response);
            });
        });
    }
    
  2. Additional Scopes Apple only supports email and name scopes. Extend the provider to handle custom logic:

    $provider = Socialite::driver('apple')->stateless();
    $provider->scopes(['email', 'name']); // Apple ignores extra scopes but won’t error.
    
  3. Webhook Validation For server-side validation (e.g., JWT), use the apple package’s verify() method:

    use Patrickbussmann\OAuth2Apple\Apple;
    
    $isValid = Apple::verify($user->token, $user->raw);
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor