Files
daily-meal-api/app/Services/SocialIdentityResolver.php
leonm ddc80956a0
CI / 🧪 Tests Laravel (push) Failing after 9s
CI / 🐳 Build & Push Images (push) Has been skipped
feat: google login
2026-08-17 10:06:35 +02:00

64 lines
2.1 KiB
PHP

<?php
namespace App\Services;
use App\Enums\SocialProvider;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Arr;
use Laravel\Socialite\Contracts\Factory as SocialiteFactory;
use Laravel\Socialite\Contracts\User as SocialiteUser;
use Laravel\Socialite\Two\AbstractProvider;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Throwable;
class SocialIdentityResolver
{
public function __construct(
private SocialiteFactory $socialite,
private AppleIdentityTokenVerifier $appleIdentityTokenVerifier,
private SocialAuthenticationNonce $socialAuthenticationNonce,
) {}
public function resolve(SocialProvider $provider, string $identityToken, ?string $nonce): SocialiteUser
{
try {
return match ($provider) {
SocialProvider::Google => $this->googleUserFromToken($identityToken, $nonce ?? ''),
SocialProvider::Apple => $this->appleIdentityTokenVerifier->userFromToken(
$identityToken,
$nonce ?? '',
),
};
} catch (HttpExceptionInterface $exception) {
throw $exception;
} catch (GuzzleException) {
abort(503, 'SOCIAL_PROVIDER_UNAVAILABLE');
} catch (Throwable) {
abort(401, 'SOCIAL_TOKEN_INVALID');
}
}
private function googleUserFromToken(string $identityToken, string $nonce): SocialiteUser
{
if (! config('services.google.client_id')) {
abort(503, 'SOCIAL_PROVIDER_NOT_CONFIGURED');
}
/** @var AbstractProvider $provider */
$provider = $this->socialite->driver(SocialProvider::Google->value);
$identity = $provider->userFromToken($identityToken);
$rawIdentity = method_exists($identity, 'getRaw') ? $identity->getRaw() : [];
if (! is_array($rawIdentity) || ! $this->socialAuthenticationNonce->consume(
SocialProvider::Google,
$nonce,
Arr::get($rawIdentity, 'nonce'),
)) {
abort(401, 'SOCIAL_TOKEN_INVALID');
}
return $identity;
}
}