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

Socialiteproviders Minecraft Evopixel Laravel Package

evopixel/socialiteproviders-minecraft-evopixel

A Laravel Socialite provider for Minecraft authentication through EvoPixel. Add Minecraft login to your PHP/Laravel app with a dedicated Socialite driver that simplifies integrating EvoPixel Minecraft accounts.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Laravel Socialite driver that runs a web Authorization Code flow with session-bound state and S256 PKCE, so the browser session — not your own code — carries the security-critical bits. Your only job is to register a Web client, keep the secret on the backend, and wire up two routes.

1. Install

composer require socialiteproviders/mcevo

You need PHP 7.4/8.x and socialiteproviders/manager 4.x (pulled in as a dependency; pin it if you already have it).

2. Register the client

// config/services.php
'mcevo' => [
    'client_id'     => env('MCEVO_CLIENT_ID'),
    'client_secret' => env('MCEVO_CLIENT_SECRET'),
    'redirect'      => env('MCEVO_REDIRECT_URI'), // must match the dashboard exactly
],

3. Hook the driver into Socialite

// app/Providers/EventServiceProvider.php
protected $listen = [
    \SocialiteProviders\Manager\SocialiteWasCalled::class => [
        \SocialiteProviders\Mcevo\McevoExtendSocialite::class.'@handle',
    ],
];

4. Two routes and one controller action

Route::get('/auth/mcevo/redirect', fn () => Socialite::driver('mcevo')->redirect());
Route::get('/auth/mcevo/callback', [McevoController::class, 'callback']);

// McevoController::callback
public function callback(Request $request)
{
    $mcevo = Socialite::driver('mcevo')->user();

    $user = User::updateOrCreate(
        ['mcevo_id' => $mcevo->getId()],
        [
            'name'          => $mcevo->getNickname(),
            'email'         => $mcevo->getEmail(),
            'minecraft_uuid' => data_get($mcevo->getRaw(), 'profile.id'),
            'minecraft_name' => data_get($mcevo->getRaw(), 'profile.name'),
            'access_token'  => $mcevo->token,
            'refresh_token' => $mcevo->refreshToken,
            'expires_at'    => now()->addSeconds($mcevo->expiresIn),
        ]
    );

    Auth::login($user, remember: true);

    return redirect()->intended('/dashboard');
}

Where to look first: the README (integration details live entirely there — scopes, the raw profile shape, and the exact key names for the Minecraft mapping). Then vendor/socialiteproviders/mcevo to confirm the getUserByToken / mapUserToObject behaviour before you rely on any raw key.

First useful use case: "Sign in with mcevo" as the primary login for a Laravel web app, persisting the Minecraft UUID/name at login so you can render skins, run /whitelist style checks, or gate a player dashboard without a second API round-trip.

Implementation Patterns

Token persistence with rotation. The provider returns a refresh token that rotates: every successful refresh invalidates the previous one. Always persist the new pair atomically.

public function refreshToken(McevoAccount $account): McevoAccount
{
    $response = Http::asForm()->post(config('services.mcevo.token_url'), [
        'grant_type'    => 'refresh_token',
        'refresh_token' => $account->refresh_token,
        'client_id'     => config('services.mcevo.client_id'),
        'client_secret' => config('services.mcevo.client_secret'),
    ])->throw();

    $account->update([
        'access_token'  => $response['access_token'],
        'refresh_token' => $response['refresh_token'] ?? $account->refresh_token,
        'expires_at'    => now()->addSeconds($response['expires_in']),
    ]);

    return $account;
}

Wrap refreshes in a lock (Cache::lock("mcevo:refresh:{$account->id}")->block(5)) — rotation plus two concurrent requests equals a dead session.

Refresh pre-emptively, not reactively. Add a 60-second buffer and refresh in middleware or a scheduled command rather than waiting for a 401 mid-request.

Revoke on logout. This release supports revocation, so use it — otherwise the refresh token outlives the session.

Http::asForm()->post(config('services.mcevo.revocation_url'), [
    'token'         => $account->refresh_token,
    'token_type_hint' => 'refresh_token',
    'client_id'     => config('services.mcevo.client_id'),
    'client_secret' => config('services.mcevo.client_secret'),
]);
$account->update(['access_token' => null, 'refresh_token' => null]);

Account linking, not account creation, as the default. Match on mcevo_id first; only fall back to email if you trust the provider's email verification. Never auto-link a provider identity to an existing password account on email match alone.

Treat the Minecraft profile as a cached projection. Store UUID + username at login, refresh on each successful login, and re-fetch when you detect a stale username. Don't call the profile endpoint on every page render.

Testing. Fake the HTTP layer rather than the driver where you care about token handling; fake the driver where you care about your controller:

Socialite::shouldReceive('driver->user')->andReturn(
    (new \Laravel\Socialite\Two\User)->map([
        'id' => 'abc', 'nickname' => 'Steve', 'token' => 't', 'refreshToken' => 'r',
        'expiresIn' => 3600, 'profile' => ['id' => 'uuid', 'name' => 'Steve'],
    ])
);

Extension points. Socialite::extend('mcevo', ...) if you need a derived driver (custom scopes, a different profile mapping). Listen to SocialiteWasCalled in one place and keep the listener thin — that's the only coupling between the package and your app.

Gotchas and Tips

  • state and the PKCE verifier live in the session. The callback will fail with a state mismatch if the session doesn't survive the round trip. Common causes: SESSION_DRIVER=array, cookie sessions across multiple app servers, a cookie domain that doesn't cover the callback host, or SameSite=Strict on a cross-site redirect. Use redis/database sessions in anything with more than one node.
  • Never call ->stateless(). It's the one line that silently disables the protection this release was built around.
  • API-only / SPA backends: the driver needs a real session on both legs. Either route the whole flow through a web-middleware group, or keep the redirect/callback on your backend and hand your SPA your own session — don't try to proxy just the callback.
  • Redirect URI must be byte-identical to what's registered — scheme, host, port, trailing slash, www. php artisan config:cache after changing it; stale config is the usual culprit for "invalid_client".
  • Rotation races. If a request refreshes while a queued job holds the old refresh token, one of them gets invalid_grant and the user is logged out. Lock, and treat invalid_grant as "force re-authentication", not "retry".
  • Revocation returns 200 even for unknown tokens (per RFC 7009). Don't infer success from the response body; just clear local state.
  • Refresh tokens are long. Use TEXT, not VARCHAR(255), and encrypt at rest (encrypted cast) — they're bearer credentials.
  • The client secret is server-side only. This flow is explicitly for web apps with a backend. A desktop/CLI/mobile client that ships the secret is compromised on day one; use a different flow for those.
  • Raw profile keys are not part of the public contract. getRaw() for the Minecraft mapping is the pragmatic path, but confirm field names against the README and assert on them in a test so a provider-side rename fails loudly instead of writing nulls.
  • PHP 7.4 support means the driver can't use PHP 8 syntax. If you subclass or copy the driver, match that constraint — or just don't subclass it. Note that Laravel 9+ already requires PHP 8, so 7.4 only matters on Laravel 8.
  • Manager 4.x changed registration from earlier majors. If you're copying a snippet from an older SocialiteProviders tutorial you'll end up with a driver that resolves to InvalidArgumentException: Driver [mcevo] is not supported. Use the SocialiteWasCalled listener form above.
  • Debugging checklist for a failing callback: session driver → cookie domain/SameSite → exact redirect URI → clock skew on expires_at → whether the account still has a refresh token (a prior failed rotation leaves it null).
  • Queues: Socialite::driver(...)->redirect() cannot run in a job (no session). Token refresh can — pass the model, not the session.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource