Weave 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

Oauth User Data Laravel Package

oryzone/oauth-user-data

Laravel package that fetches and normalizes user profile data from OAuth providers such as Google, Facebook, and GitHub. It offers a unified API to retrieve names, emails, avatars, and other fields after social login, with caching and configurable drivers for each provider.

View on GitHub
Deep Wiki
Context7

Getting Started

Before writing a line of integration code, verify the package still fits the job. It is a thin, unmaintained (last release 2014) extension for lusitanian/oauth whose only responsibility is calling a provider's profile endpoint and returning a normalized UserData object. Treat it as a profile extractor, not an auth stack — it does not manage Laravel sessions, users, or guards.

composer require oryzone/oauth-user-data lusitanian/oauth

Look first at src/Oryzone/OAuthUserData/Provider/ to confirm the exact class names and constructor signatures for the current version, then at the UserData value object to see which fields (email, name, avatar, locale) are populated per provider. The provider classes wrap a Lusitanian\OAuth\OAuth service instance, so almost every usage starts by constructing that service through Lusitanian's ServiceFactory.

The first realistic use case is a classic "Sign in with GitHub" flow:

  1. Build an OAuth service for the provider with your client ID/secret and a callback URL.
  2. Redirect the user to getAuthorizationUri() with the required scopes.
  3. On callback, retrieve the access token from the code.
  4. Hand the authenticated service to the matching Oryzone\OAuthUserData\Provider\* class and call getUserData().
  5. Map the returned object onto your users table.
// app/Services/OAuth/ProfileFetcher.php
public function fetch(string $provider, string $code): UserData
{
    $service = $this->factory->createService($provider, $this->credentials($provider), $this->callbackUrl());
    $service->requestAccessToken($code);

    $class = 'Oryzone\\OAuthUserData\\Provider\\' . ucfirst($provider);
    return (new $class($service))->getUserData();
}

Bind the fetcher and the underlying ServiceFactory as singletons in a service provider so credentials live in config/services.php and never in the controller.

Implementation Patterns

Wrap it immediately. Do not call provider classes from controllers, jobs, or listeners. A single ProfileFetcher (or OAuthProfileRepository) that returns your own DTO insulates the rest of the app from the package's 2014-era API and makes it replaceable by Socialite later.

Normalize into a first-party DTO. Different providers return different shapes and nullability. Convert UserData into an immutable value object you own:

final class ExternalProfile
{
    public function __construct(
        public readonly string $provider,
        public readonly string $providerId,
        public readonly ?string $email,
        public readonly ?string $name,
        public readonly ?string $avatarUrl,
        public readonly array $raw,
    ) {}
}

Separate login from linking. Day-to-day you will need both "register/login with provider" and "connect provider to an existing account." Model them as two routes (/auth/{provider}/redirect and /auth/{provider}/link) and a shared callback that branches on whether auth()->check() is true. Store provider, provider_id, and access_token (encrypted cast) in a social_accounts table rather than columns on users; it makes supporting multiple providers trivial.

Use an event for provisioning. On first-time profile fetch, dispatch ExternalUserRegistered and let a listener create the local user, assign the default role, and queue a welcome mail. Keep the callback controller under ~20 lines.

Cache and localize avatars. Provider avatar URLs are hotlinked, sometimes expiring, and frequently blocked by referrer policies. Download to storage/app/public/avatars/{uuid}.jpg during onboarding and store the local path — the UserData object's image URL is a one-time bootstrap value, not something to persist.

Test against a mocked OAuth service. Because the provider classes call request() on the injected service, you can bind a fake via Mockery and return canned profile JSON. Keep a small fixture per provider (tests/Fixtures/providers/github.json). Never hit live endpoints in CI; OAuth callbacks need a Http::fake()/mocked service, not a real redirect.

Configuration over hardcoding. Add a config/oauth.php with each provider's scopes, credential keys, and the Oryzone class to instantiate. That config becomes the single extension seam when a provider's API changes:

'google' => [
    'class'  => Oryzone\OAuthUserData\Provider\Google::class,
    'scopes' => ['email', 'profile'],
],

Gotchas and Tips

The endpoints are stale. Most providers in this package target APIs from 2013–2014 (Google+ for profile data, Facebook Graph v1, older LinkedIn v1). Several will return 404/403 or empty payloads today. Plan to subclass the affected provider and override its profile-fetch method with the current endpoint, or better, wrap the raw HTTP call yourself and use only the package's UserData object for normalization.

Scopes are not optional. getUserData() frequently returns a UserData with email = null because the authorization request didn't include the email scope. Always pass the scope explicitly on redirect and treat email as nullable in your mapping — do not assume getEmail() is present, and always have a "complete your profile" fallback.

OAuth 1 vs OAuth 2 divergence. Twitter is OAuth 1.0a; GitHub/Google/Facebook are OAuth 2. The redirect and token-exchange steps come from lusitanian/oauth, not this package, so your fetcher must branch on the provider's OAuth version before calling requestAccessToken. Get that wrong and you'll get cryptic TokenNotFoundExceptions.

Session-statefulness of the underlying library. Lusitanian's default token storage is session-based, which is fine for browser redirects but breaks for API clients, queued jobs, or multi-tab linking. If you need stateless flows, override the token storage or persist tokens yourself and reconstruct the service per request.

Dependency conflicts. This package pulls an old Guzzle/PSR-0 stack. If your Laravel app's other packages require modern Guzzle, Composer will either refuse to install or pin you to an ancient version. Check composer why guzzlehttp/guzzle before committing, and consider isolating the fetch behind a separate internal HTTP call so you can drop the dependency later.

Provider ID extraction is provider-specific. There is no uniform getId() guarantee across providers; some expose uid, others id under a nested key. Read the fixture for each provider once, write the mapping, and snapshot-test it — do not assume the field name carries over.

Debugging tips. Log the raw profile array (redacting tokens and email where required) at debug level during development; when a provider changes its response shape, the raw payload makes the fix obvious. Catch the library's OAuthException and the HTTP-layer exceptions separately, and map both to a single user-facing "could not sign you in" flash message.

Extension points. The clean seams are (a) the provider class itself — subclass and override the profile method; (b) the UserData object — map into your DTO so the rest of the app never imports the package namespace; (c) the fetcher binding — swap the implementation for Socialite or a raw HTTP client without touching controllers. Given the package's age, assume you will exercise (a) within a year and design the binding so doing so is a one-file change.

Consider Socialite instead for greenfield work. If you are starting a new Laravel app today, laravel/socialite covers every provider this package supports, is maintained, and integrates natively with the framework. Use this package only when retrofitting an existing Lusitanian-based codebase or when you explicitly need its provider-specific profile normalization.

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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core