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

Instagram Laravel Package

socialiteproviders/instagram

Instagram OAuth provider for Laravel Socialite. Lets users log in with Instagram and returns a Socialite user object. Install via Composer, configure your client ID and secret, then add the provider to Socialite config and redirect/callback routes.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the split package (it pulls in socialiteproviders/manager automatically):

composer require socialiteproviders/instagram

Register the provider's listener so Socialite learns the instagram driver. On Laravel 10 and below, add it to app/Providers/EventServiceProvider.php:

protected $listen = [
    \SocialiteProviders\Manager\SocialiteWasCalled::class => [
        \SocialiteProviders\Instagram\InstagramExtendSocialite::class.'@handle',
    ],
];

On Laravel 11+ there is no EventServiceProvider by default, so register it in AppServiceProvider::boot():

use Illuminate\Support\Facades\Event;
use SocialiteProviders\Manager\SocialiteWasCalled;

Event::listen(function (SocialiteWasCalled $event) {
    $event->extendSocialite('instagram', \SocialiteProviders\Instagram\Provider::class);
});

Add credentials to config/services.php and .env:

'instagram' => [
    'client_id'     => env('INSTAGRAM_CLIENT_ID'),
    'client_secret' => env('INSTAGRAM_CLIENT_SECRET'),
    'redirect'      => env('INSTAGRAM_REDIRECT_URI'),
],

Where to look first: the docs at socialiteproviders.com/Instagram and the provider class itself at vendor/socialiteproviders/instagram/src/Provider.php — it is small and tells you exactly which endpoints, scopes, and user fields you are getting.

First use case — the classic "Log in with Instagram" button. Two routes, one controller method each:

Route::get('/auth/instagram', fn () => Socialite::driver('instagram')->redirect());
Route::get('/auth/instagram/callback', [InstagramController::class, 'callback']);
public function callback()
{
    $ig = Socialite::driver('instagram')->user();

    // $ig->getId(), ->getNickname(), ->getName(), ->getAvatar(), ->token
    Auth::login(User::firstOrCreateFromInstagram($ig));

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

Implementation Patterns

Separate "login" from "connect". Use two entry routes — one that authenticates a new/returning user, one that attaches an Instagram account to an already-authenticated user — and branch on Auth::check() inside the callback. This is the cleanest way to support both flows with one provider.

Persist tokens, not just the user. Instagram tokens expire, so store them on a social_accounts table keyed by (provider, provider_id) and keep token, refresh_token, and expires_at. This makes re-login, unlinking, and background refresh possible later:

$account = SocialAccount::updateOrCreate(
    ['provider' => 'instagram', 'provider_id' => $ig->getId()],
    [
        'user_id'       => $user->id,
        'nickname'      => $ig->getNickname(),
        'avatar'        => $ig->getAvatar(),
        'token'         => $ig->token,
        'refresh_token' => $ig->refreshToken,
        'expires_at'    => $ig->expiresIn ? now()->addSeconds($ig->expiresIn) : null,
    ]
);

Stateless mode for mobile/SPA. When the client already obtained an access token, skip the redirect/state dance:

$ig = Socialite::driver('instagram')->stateless()->userFromToken($request->token);

Handle the error branch. Instagram redirects back with ?error=access_denied&error_description=... when the user cancels — check $request->has('error') before calling ->user(), otherwise you get an unhelpful exception.

Testing. Mock the Socialite driver rather than hitting the network:

$mock = Mockery::mock(\Laravel\Socialite\Contracts\Provider::class);
$mock->shouldReceive('user')->andReturn($socialiteUser);
Socialite::shouldReceive('driver')->with('instagram')->andReturn($mock);

Wrap the callback in a try/catch for InvalidStateException and redirect the user back to the login page. State mismatches are common in production and should not produce a 500.

Gotchas and Tips

  • The listener is mandatory. Forget it and Socialite::driver('instagram') throws Driver [instagram] is not supported. This is the #1 install mistake.
  • Clear config cache after editing services.php. php artisan config:cache stale caches are the #2 cause of "missing client_id" errors.
  • No email. Instagram does not return an email address, so $ig->getEmail() is usually null. Plan your user-creation flow accordingly — either require email post-signup or generate a placeholder.
  • Exact redirect URI match. The value in services.php must match the URI registered in the Meta app dashboard character-for-character — scheme, host, port, trailing slash. Facebook/Meta requires HTTPS for production callbacks.
  • State/session fragility. The callback must land on the same session/domain as the redirect. Third-party cookie blocking, SESSION_DOMAIN mismatches, and proxy/CDN hostname differences all produce InvalidStateException. Stateless mode avoids this entirely where appropriate.
  • Scopes need app review. Beyond your own test users, Instagram scopes (e.g. user_profile, user_media) require Meta App Review before they work in production. Set defaults via ->scopes([...]) or a 'scopes' config key.
  • Token lifetime. Short-lived tokens last roughly an hour; long-lived tokens (exchanged separately) last ~60 days. The package surfaces token/expiresIn but does not refresh for you — schedule a refresh job and store expires_at.
  • API surface changed. Instagram's Basic Display API was sunset in late 2024 in favor of "Instagram API with Instagram Login". Confirm the currently installed provider version still targets a live endpoint; if not, pin the version that does or override getAuthUrl()/getTokenUrl() in a subclass.
  • Avatar URLs expire. getAvatar() may return a time-limited CDN URL or null; download and re-host it if you display it long-term.
  • Debug by dumping the raw payload. $ig->getRaw() returns the full API response array — invaluable when a field you expect is missing or renamed.
  • Extension points. Subclass SocialiteProviders\Instagram\Provider and override mapUserToObject(), getAuthUrl(), or getTokenUrl() if you need custom scopes, endpoint versions, or extra fields. Register your subclass instead of the vendor one in the event listener.
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.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle