Table of contents
In this post, I'm sharing how to implement the Laravel 8 and 9 user impersonation. Usually using this functionality to log in on behalf of admin users. User impersonation is useful when managing users who want to access their users and check what they did in their accounts.
Â
Take note that doing this you must be careful because it could give you security issues and your user's privacy. So you must double-check your code if implemented correctly.
Â
Â
Â
To shorten this tutorial I'm using my previous code that has authentication and roles already. You can view it here if you want to use it.
Â
Step 1: Install the package
I'm using the package of 404labfr Laravel impersonate. Run the following command to your local project.
composer require lab404/laravel-impersonate
Â
Step 2: Setup User Model
To your User model use this Impersonate. See below the whole model code.
<?php
namespace App\Models;
use Laravel\Sanctum\HasApiTokens;
use Spatie\Permission\Traits\HasRoles;
use Illuminate\Notifications\Notifiable;
use Lab404\Impersonate\Models\Impersonate;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable, HasRoles, Impersonate;
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'users';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'email',
'username',
'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
/**
* Always encrypt password when it is updated.
*
* @param $value
* @return string
*/
public function setPasswordAttribute($value)
{
$this->attributes['password'] = bcrypt($value);
}
}
Â
Â
Step 3: Routes
Add the 2 lines of routes. See the below example:
Route::get('/{user}/impersonate', 'UsersController@impersonate')->name('users.impersonate');
Route::get('/leave-impersonate', 'UsersController@leaveImpersonate')->name('users.leave-impersonate');
Â
NOTE: You must put a restriction for this route that is not accessible for not permitted roles.
Â
Step 4: Controller
Add the following methods below to your UsersController.
public function impersonate(User $user)
{
auth()->user()->impersonate($user);
return redirect()->route('home.index');
}
public function leaveImpersonate()
{
auth()->user()->leaveImpersonation();
return redirect()->route('home.index');
}
Â
Â
Step 5: Table Users List
In your index blade file for table users list add the following code.
@role('Admin')
<td>
@if($user->id != auth()->id())
<a href="{{ route('users.impersonate', $user->id) }}" class="btn btn-warning btn-sm">Impersonate</a>
@endif
</td>
@endrole
Â
As you can see above that only Admin can see this column.
Â
Step 6: Navbar Blade (Leaving impersonation)
To your navbar you can put this in the menu and what you like. To leave the user impersonation. See the sample code below:
@auth
<div class="text-end">
@if(session('impersonated_by'))
<a href="{{ route('users.leave-impersonate') }}" class="btn btn-outline-light me-2">Leave Impersonation</a>
@endif
</div>
@endauth
Â
Take note: If you are using my previous tutorial don't forget to run the following command below:
php artisan permission:create-permission-routes
Â
To register the new routes as permissions.
Â
And don't forget to add permission for this "users.leave-impersonate" to your user roles so that if the admin wants to leave the impersonation the regular user has access to that route.
Â
And don't forget also to add these permissions to your admin role (users.impersonate, users.leave-impersonate)
Â
Â
I hope it helps. Thank you for reading :)
Read next