laravel-impersonate icon indicating copy to clipboard operation
laravel-impersonate copied to clipboard

I can successfully impersonate, but leaving will log out

Open sathia-musso opened this issue 3 years ago • 20 comments

Hi, I'm using laravel 8 and jetstream, I'm not sure why I am able to impersonate any user I need but then when I fire route('impersonate.leave') i'm kicked to the login page. I find it odd that it can impersonate a user but can't get back to previous session. Any idea?

sathia-musso avatar Mar 04 '21 14:03 sathia-musso

I am also facing same issue. Did you find any solution for this?

Thanks

dhruva81 avatar May 02 '21 16:05 dhruva81

nope, I've decide to make my own impersonating tool, it is very limited so, not really worth sharing.

sathia-musso avatar May 02 '21 17:05 sathia-musso

I'm facing the same issue, any info on this?

mdcass avatar May 14 '21 08:05 mdcass

I would say that this is abandonware

sathia-musso avatar May 14 '21 08:05 sathia-musso

No issue with Jetstream and Impersonate. If you need more info, please paste your config files here.

MarceauKa avatar May 14 '21 12:05 MarceauKa

Hi, i'm using the near-default config file

<?php

return [

    /**
     * The session key used to store the original user id.
     */
    'session_key' => 'impersonated_by',

    /**
     * The session key used to stored the original user guard.
     */
    'session_guard' => 'impersonator_guard',

    /**
     * The session key used to stored what guard is impersonator using.
     */
    'session_guard_using' => 'impersonator_guard_using',

    /**
     * The default impersonator guard used.
     */
    'default_impersonator_guard' => 'web',

    /**
     * The URI to redirect after taking an impersonation.
     *
     * Only used in the built-in controller.
     * * Use 'back' to redirect to the previous page
     */
    'take_redirect_to' => '/',

    /**
     * The URI to redirect after leaving an impersonation.
     *
     * Only used in the built-in controller.
     * Use 'back' to redirect to the previous page
     */
    'leave_redirect_to' => '/admin',

];

mdcass avatar May 14 '21 14:05 mdcass

Also note i'm using Jetstream and Fortify (both dig in to the guards I believe)

mdcass avatar May 14 '21 14:05 mdcass

I'm also using Jetstream and I faced this issue. The problem is that the guard password session variable is not updated properly. If you use the web guard adding the value to the session manually will fix the issue:

    public function quietLogin(Authenticatable $user)
    {
        $this->updateSession($user->getAuthIdentifier());
        $this->session->put([
            'password_hash_web' =>  $user->getAuthPassword(),
        ]);

        $this->setUser($user);
    }

gazben avatar May 15 '21 14:05 gazben

I'm facing the same issue, but on the start of impersonating, when I hit the 'impersonate/take' route.

Jetstream(Inertia) + Fortify.

BKirev avatar May 29 '21 23:05 BKirev

I created a fix for this issue but I didn't do a PR as it already has a pending here. Unfortunately it has not yet been approved.

Anyone who wants a simple solution can use a patch: https://gist.github.com/dmandrade/f8d7e16d32a18e250f933e9ca4705b71

To apply it automatically just install the vaimo/composer-patches package.

Save this patch file in PROJECT_ROOT/patches folder.

In composer.json add:

    "extra": {
        ...
        "patcher": {
            "search": "patches"
        }
    }

After adding the patch file and update composer.json run composer patch:apply

dmandrade avatar Jun 02 '21 01:06 dmandrade

Instead of using a patcher, why don't you use the events like so?

<?php

class EventServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Event::listen(function (TakeImpersonation $event) {
            session()->put([
                'password_hash_web' =>  $event->impersonated->getAuthPassword(),
                'password_hash_sanctum' => $event->impersonated->getAuthPassword(),
            ]);
        });

        Event::listen(function (LeaveImpersonation $event) {
            session()->put([
                'password_hash_web' =>  $event->impersonator->getAuthPassword(),
                'password_hash_sanctum' => $event->impersonator->getAuthPassword(),
            ]);
        });
    }
}

masterix21 avatar Jun 15 '21 09:06 masterix21

@masterix21 No special reason. I already use patches for this type of situation until an update comes out.

dmandrade avatar Jun 16 '21 14:06 dmandrade

Understandable, but - IMHO - perhaps it's safer to use events in production.

masterix21 avatar Jun 17 '21 10:06 masterix21

Thank you @masterix21 This also pointed me to solution for my case where I'm using Laravel Sanctum, where instead of password_hash_web I used password_hash_sanctum

antongorodezkiy avatar Dec 09 '21 22:12 antongorodezkiy

I'm also using Jetstream and I faced this issue. The problem is that the guard password session variable is not updated properly. If you use the web guard adding the value to the session manually will fix the issue:

    public function quietLogin(Authenticatable $user)
    {
        $this->updateSession($user->getAuthIdentifier());
        $this->session->put([
            'password_hash_web' =>  $user->getAuthPassword(),
        ]);

        $this->setUser($user);
    }

Thanks a lot man!!! I spent half a day to find the core of the problem and it helped me!

Dmitry-Allread-Return avatar Jul 11 '22 14:07 Dmitry-Allread-Return

I face the same issue with jetstream. Where I have to put this script? So all I need to do is paste this script?

jonathanoeijoeng avatar Jul 25 '22 10:07 jonathanoeijoeng

Instead of using a patcher, why don't you use the events like so?

<?php

class EventServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Event::listen(function (TakeImpersonation $event) {
            session()->put([
                'password_hash_web' =>  $event->impersonated->getAuthPassword(),
            ]);
        });

        Event::listen(function (LeaveImpersonation $event) {
            session()->put([
                'password_hash_web' =>  $event->impersonator->getAuthPassword(),
            ]);
        });
    }
}

For anyone else here using jetstreams and sanctum you will need to adjust the above to:

    public function boot()
    {
        Event::listen(function (TakeImpersonation $event) {
            session()->put([
                'password_hash_sanctum' => $event->impersonated->getAuthPassword(),
            ]);
        });

        Event::listen(function (LeaveImpersonation $event) {
            session()->put([
                'password_hash_sanctum' => $event->impersonator->getAuthPassword(),
            ]);
        });
    }

within the EventServiceProvider in: App\Providers\EventServiceProvider.php

tonypartridger avatar Jan 16 '23 09:01 tonypartridger

Instead of using a patcher, why don't you use the events like so?

<?php

class EventServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Event::listen(function (TakeImpersonation $event) {
            session()->put([
                'password_hash_web' =>  $event->impersonated->getAuthPassword(),
                'password_hash_sanctum' => $event->impersonated->getAuthPassword(),
            ]);
        });

        Event::listen(function (LeaveImpersonation $event) {
            session()->put([
                'password_hash_web' =>  $event->impersonator->getAuthPassword(),
                'password_hash_sanctum' => $event->impersonator->getAuthPassword(),
            ]);
        });
    }
}

So happy with this. Works great

casbizz avatar Jan 22 '23 11:01 casbizz

I was in the same situation, but I found a very easy work-around. In routes/web.php, do not use the auth:sanctum middleware, just auth, e.g.:

Route::middleware([
    'auth',
    config('jetstream.auth_session'),
    'verified',
])->group(function () {
    Route::impersonate();
});

Use auth:sanctum for the rest of your routes. This solved being getting logged out when leaving impersonation.

selfsimilar avatar Feb 03 '23 23:02 selfsimilar

I was in the same situation, but I found a very easy work-around. In routes/web.php, do not use the auth:sanctum middleware, just auth, e.g.:

Route::middleware([
    'auth',
    config('jetstream.auth_session'),
    'verified',
])->group(function () {
    Route::impersonate();
});

Use auth:sanctum for the rest of your routes. This solved being getting logged out when leaving impersonation.

If you don't need auth:sanctum (which is most people), then this is the right solution.

aarreedd avatar Sep 05 '23 20:09 aarreedd