Impersonation URL 403s after impersonate
I'm using latest version of Laravel (5.8) and your package. I've installed using the route macro Route::impersonate() and have the following in my User model:
/**
* @return bool
*/
public function canImpersonate()
{
// For example
return $this->hasRole('admin');
}
hasRole is part of the very popular Spatie Laravel Persmissions package.
When logged in as an admin, if I visit the route created by your package I'm taken to: /impersonate/take/3
This page 403s. However, when I then visit / I find I'm logged in as the impersonated user (expected behaviour). It looks like the impersonation is potentially being run before middleware or that something else is going on? The route macro is outside of any groups or middleware.
/impersonate/leave works exactly as expected and redirects me correctly.
Any ideas how I can solve this?
I am facing the same issue
In your own debugging, what's causing the 403 response? Where exactly is it happening?
Solved:
Add the folllowing in the web.php
Route::impersonate();
And then in your blade do sth like this or according to your need:
@php
$users = \Corals\User\Models\User::all();`
@endphp
@foreach($users as $user)
@canBeImpersonated($user)
<a href="{{ route('impersonate', $user->id) }}">Impersonate this user</a>
@endCanBeImpersonated
@endforeach
I'm using latest version of Laravel (5.8) and your package. I've installed using the route macro
Route::impersonate()and have the following in my User model:/** * @return bool */ public function canImpersonate() { // For example return $this->hasRole('admin'); }
hasRoleis part of the very popular Spatie Laravel Persmissions package.When logged in as an admin, if I visit the route created by your package I'm taken to: /impersonate/take/3
This page 403s. However, when I then visit / I find I'm logged in as the impersonated user (expected behaviour). It looks like the impersonation is potentially being run before middleware or that something else is going on? The route macro is outside of any groups or middleware.
/impersonate/leave works exactly as expected and redirects me correctly.
Any ideas how I can solve this?
Do you use the web guard?
I have the same issue. One cannot double impersonate (impersonate another user when already impersonating). What could solve this is a @isNotImpersonating directive. You can then show the "impersonate" button only when you are not impersonating already
So I am doing the following:
Added the inverse blade directive of @isImpersonating:
AppServiceProvider.php:
public function boot()
{
\Blade::directive('isNotImpersonating', function () {
return "<?php if (!is_impersonating()) : ?>";
});
\Blade::directive('endIsNotImpersonating', function () {
return '<?php endif; ?>';
});
}
Then in your blade template you can use:
@isNotImpersonating
<a class="dropdown-item"
href="{{ route('impersonate', $resellerUser->id) }}">
Impersonate
</a>
@endIsNotImpersonating
Hence not showing the button when already impersonating and therefore not double impersonating (which gives the 403 error).
I've not found any need for another Blade directive.
I implement it like the following. The @canImpersonate checks for role authorization. @canBeImpersonated verifies that the indicated user is allowed to be impersonated. The criteria for these are in the User model, also shown below.
I think simply doing the canBeImpersonated() method override is enough to prevent the double-impersonation you mention, and also allows you control over additional criteria you may wish to incorporate.
User "show" template:
@canImpersonate
@canBeImpersonated($user)
<div class="btn-group float-right d-print-none" role="group" aria-label="Impersonate">
<a href="{{ route('impersonate', $user->id) }}"><button type="button" class="btn btn-success text-center"><i class="fa fa-user-circle fa-lg" title="Impersonate this user"></i></button></a>
</div>
@endCanBeImpersonated
@endCanImpersonate
Nav bar next to Logout:
@impersonating
<a class="bg-danger dropdown-item" href="{{ route('impersonate.leave') }}" data-shortcut="leave"><i class="fa fa-btn fa-times-circle" aria-hidden="true"></i>Leave Impersonation</a>
@endImpersonating
User model methods which override the Trait defaults:
/**
* Return true or false whether the user can impersonate another user.
*
*/
public function canImpersonate(): bool
{
return $this->hasRole('Admin') || $this->hasRole('Super-Admin');
}
/**
* Return boolean whether the user can be impersonated.
* Here we deny impersonation of oneself (or double-impersonating) as that would be pointless.
*/
public function canBeImpersonated(): bool
{
return $this->id != Auth::id();
}