laravel-impersonate
laravel-impersonate copied to clipboard
After Auth::user()->impersonate($otherUser) I'm getting logged out
I've installed the package as described and tried to impersonate other user. But I'm always getting logged out.
Here is my code:
$anotherUser = User::find(9); Auth::user()->impersonate($anotherUser); return redirect()->route('dashboard');
Ah. And I'm using Jetsream
I'm experiencing the same issue after updating composer:
- Upgrading laravel/framework (v9.3.1 => v9.4.1)
It was working fine with Laravel 9.3.1, and breaks after upgrading to 9.4.x
Here is the Laravel changelog: https://github.com/laravel/framework/blob/9.x/CHANGELOG.md#v940---2022-03-08
Quick fix is to comment out the following line in Illuminate\Foundation\Http\Kernel.php
:
protected $middlewarePriority = [
\Illuminate\Cookie\Middleware\EncryptCookies::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class,
\Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class,
// Comment out this line:
// \Illuminate\Contracts\Session\Middleware\AuthenticatesSessions::class,
// Add this line:
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
];
I do not have anything like \Illuminate\Contracts\Session\Middleware\AuthenticatesSessions::class, in Illuminate\Foundation\Http\Kernel.php
I tried to comment out this line instead: \Laravel\Jetstream\Http\Middleware\AuthenticateSession::class,
but it did not help. I'm still getting log out.
And I'd like to comment one important thing to the maintainer of this package. I can understand that the package can not work with some other software like JetStream. But for a f..k sake why didn't you warn us about it? I really appreciate your hard work and I know this package is free and comes with no guarantee whatsoever but I feel that respect should be mutual. I just lost many hours trying to make work something which is faulty. If the author was honest and put any information about the situation in the readme it would spare me hours of useless work.
This should now be fixed if you upgrade to Laravel Framework 9.5.1: https://github.com/laravel/framework/pull/41491
Update: after checking, it didn't resolve it for me, still experiencing the same issue.
@core45 I fixed this one by updating the middleware of the routes generated by jetstream
-Route::group(['middleware' => ['auth:sanctum', 'verified']], function (): void {
+Route::group(['middleware' => ['auth:web', 'verified']], function (): void {
//
});
Im using laravel nova to impersonate and nova is using a web
auth guard. So the nova and jetstream was not using the same guard. Because by default the jetstream's guard is using sanctum
.
This package when impersonating is logging in the user using the current guard which is web
but redirects to the dashboard in jetstream which is a sanctum
guard.
So, either removing \Laravel\Jetstream\Http\Middleware\AuthenticateSession::class
from App\Http\Kernel.php
or changing sanctum
to web
in the routes file seems to fix this with Jetstream. Does anyone know the implications of doing any of those options?
@seabasss
The main reason why auth:sanctum
is in your routes/web.php
can be read in the docs
You may be wondering why we suggest that you authenticate the routes within your application's routes/web.php file using the sanctum guard. Remember, Sanctum will first attempt to authenticate incoming requests using Laravel's typical session authentication cookie. If that cookie is not present then Sanctum will attempt to authenticate the request using a token in the request's Authorization header. In addition, authenticating all requests using Sanctum ensures that we may always call the tokenCan method on the currently authenticated user instance:
So basically if you do not need sanctum in your web routes, use auth:web
Which is what I did and it fixed the issue.
But nevertheless it would be interesting to know why impersonation with auth:sanctum
worked for me in laravel 8 and not in laravel 9
Thanks for the info! It actually worked in 9 for me up until v9.4. And it works with sanctum for me after updating some files to reflec latest jetstream, however it doesn’t work if I add the new jetstream config parameter in the route middleware.
A simple solution to get the impersonating working for a Jetstream/Sanctum setup is to use the event TakeImpersonation and add the missing session key required for Sanctum authentification
Event::listen(\Lab404\Impersonate\Events\TakeImpersonation::class,
function(\Lab404\Impersonate\Events\TakeImpersonation $event) {
session()->put('password_hash_sanctum', $event->impersonated->getAuthPassword());
});
still working on the LeaveImpersonation.
Facing the same issue any luck?
A simple solution to get the impersonating working for a Jetstream/Sanctum setup is to use the event TakeImpersonation and add the missing session key required for Sanctum authentification
Event::listen(\Lab404\Impersonate\Events\TakeImpersonation::class, function(\Lab404\Impersonate\Events\TakeImpersonation $event) { session()->put('password_hash_sanctum', $event->impersonated->getAuthPassword()); });
still working on the LeaveImpersonation.
Where do you put that? Thx
You put it in the boot method of your EventServiceProvider
Event::listen(function(\Lab404\Impersonate\Events\TakeImpersonation $event) {
session()->put('password_hash_sanctum', $event->impersonated->getAuthPassword());
});
I am using latest L9, without Jetstream, and impersonating gets me to login page. If I comment AuthenticateSession middleware, it works. Did anyone face this issue too ? How did you solve it ?
A simple solution to get the impersonating working for a Jetstream/Sanctum setup is to use the event TakeImpersonation and add the missing session key required for Sanctum authentification
Event::listen(\Lab404\Impersonate\Events\TakeImpersonation::class, function(\Lab404\Impersonate\Events\TakeImpersonation $event) { session()->put('password_hash_sanctum', $event->impersonated->getAuthPassword()); });
still working on the LeaveImpersonation.
All cool and beans mate, thanks a lot, I think this is the cleanest of the options.
Were you able to get the LeaveImpersonation working too?
A simple solution to get the impersonating working for a Jetstream/Sanctum setup is to use the event TakeImpersonation and add the missing session key required for Sanctum authentification
Event::listen(\Lab404\Impersonate\Events\TakeImpersonation::class, function(\Lab404\Impersonate\Events\TakeImpersonation $event) { session()->put('password_hash_sanctum', $event->impersonated->getAuthPassword()); });
still working on the LeaveImpersonation.
All cool and beans mate, thanks a lot, I think this is the cleanest of the options.
Were you able to get the LeaveImpersonation working too?
Sadly not, Its not currently a problem, as when logging in as an admin user, i just redirect to the admin area instead.
I was able to get leave working thanks to @matt127127 @m7vm7v looks like there is an impersonator object on the event, for anyone else just throw this in a listener or right on the web.php
Event::listen(\Lab404\Impersonate\Events\TakeImpersonation::class,
function(\Lab404\Impersonate\Events\TakeImpersonation $event) {
session()->put('password_hash_sanctum', $event->impersonated->getAuthPassword());
});
Event::listen(\Lab404\Impersonate\Events\LeaveImpersonation::class,
function(\Lab404\Impersonate\Events\LeaveImpersonation $event) {
session()->put('password_hash_sanctum', $event->impersonator->getAuthPassword());
});
```
I was able to get leave working thanks to @matt127127 @m7vm7v looks like there is an impersonator object on the event, for anyone else just throw this in a listener or right on the web.php
Event::listen(\Lab404\Impersonate\Events\TakeImpersonation::class, function(\Lab404\Impersonate\Events\TakeImpersonation $event) { session()->put('password_hash_sanctum', $event->impersonated->getAuthPassword()); }); Event::listen(\Lab404\Impersonate\Events\LeaveImpersonation::class, function(\Lab404\Impersonate\Events\LeaveImpersonation $event) { session()->put('password_hash_sanctum', $event->impersonator->getAuthPassword()); }); ```
@illusive-ch I have tried using the LeaveImpersonation::class but to no avail, If you manage to get it working i would love to see how you did it.
@matt127127 thats exactly what I put in my routes file to get it to stop from logging out when u leave impersonation.
@matt127127 thats exactly what I put in my routes file to get it to stop from logging out when u leave impersonation.
@illusive-ch What version of Laravel are you using, i'm using 9.17 and it just doesn't want to play ball for me.
@matt127127
> art --version
Laravel Framework 9.13.0
When I set this up I setup my own routes as well let me get the code for you: web.php
Event::listen(\Lab404\Impersonate\Events\TakeImpersonation::class,
function(\Lab404\Impersonate\Events\TakeImpersonation $event) {
session()->put('password_hash_sanctum', $event->impersonated->getAuthPassword());
});
Event::listen(\Lab404\Impersonate\Events\LeaveImpersonation::class,
function(\Lab404\Impersonate\Events\LeaveImpersonation $event) {
session()->put('password_hash_sanctum', $event->impersonator->getAuthPassword());
});
Route::middleware([
'superadmin'])
->name('admin.')
->prefix('admin')
->group(function () {
Route::resource('user', \App\Http\Controllers\Admin\UserController::class);
Route::get('user/{user}/impersonate', '\App\Http\Controllers\Admin\UserController@impersonate')->name('user.impersonate');
Route::get('user/{user}/leave-impersonate', '\App\Http\Controllers\Admin\UserController@leaveImpersonate')->name('user.leave-impersonate');
});
Usercontroller.php
public function impersonate(User $user)
{
auth()->user()->impersonate($user);
return redirect()->route('dashboard');
}
public function leaveImpersonate()
{
auth()->user()->leaveImpersonation();
return redirect()->route('dashboard');
}
Let me know if that works for you
@illusive-ch Sadly that didn't work, it seemed to make it worse for me, i couldn't even impersonate.
For me it is working with default setup of this module without any events on local valet setup but not on production server (forge). I am using spatie/laravel-permissons and sanctum with Jetstream
Still facing this issue with Jetstream..
Event::listen(\Lab404\Impersonate\Events\TakeImpersonation::class,
function(\Lab404\Impersonate\Events\TakeImpersonation $event) {
session()->put('password_hash_sanctum', $event->impersonated->getAuthPassword());
});
Event::listen(\Lab404\Impersonate\Events\LeaveImpersonation::class,
function(\Lab404\Impersonate\Events\LeaveImpersonation $event) {
session()->put('password_hash_sanctum', $event->impersonator->getAuthPassword());
});
Route::impersonate();
Can you please try this?
Event::listen(\Lab404\Impersonate\Events\TakeImpersonation::class, function(\Lab404\Impersonate\Events\TakeImpersonation $event) { session()->put('password_hash_sanctum', $event->impersonated->getAuthPassword()); }); Event::listen(\Lab404\Impersonate\Events\LeaveImpersonation::class, function(\Lab404\Impersonate\Events\LeaveImpersonation $event) { session()->put('password_hash_sanctum', $event->impersonator->getAuthPassword()); }); Route::impersonate();
Can you please try this?
This does not seem to work. After a fresh deploy I could impersonate once. Leaving this impersonation did not work and further impersonation did not work as well. I am getting logged out.
On my local machine the default is working (without any need of manipulation). On the laravel forge server with deploying over envoyer it is not working - even with your manipulation.
I'm using Laravel 8 + Inertia Js for authentication using Fortify but impersonating not working logged out as well, kindly someone helps me out with this issue, maybe it is working on simple Laravel older versions but in with Inertia js + Fortify it is not working I tried all above solutions.
With jetstream check the jetstream config file, as this also has 'guard' set to sanctum change this to 'web'
` /* |--------------------------------------------------------------------------
Jetstream Guard |
---|
Here you may specify the authentication guard Jetstream will use while |
authenticating users. This value should correspond with one of your |
guards that is already present in your "auth" configuration file. |
*/
'guard' => 'web',`
With jetstream check the jetstream config file, as this also has 'guard' set to sanctum change this to 'web'
` /* |-------------------------------------------------------------------------- | Jetstream Guard |-------------------------------------------------------------------------- | | Here you may specify the authentication guard Jetstream will use while | authenticating users. This value should correspond with one of your | guards that is already present in your "auth" configuration file. | */
'guard' => 'web',`
There is no "guard" section in my jetstream config file.