DEV Community

Cover image for Laravel 8 and 9 User Impersonation Example
codeanddeploy
codeanddeploy

Posted on

Laravel 8 and 9 User Impersonation Example

Originally posted @ https://codeanddeploy.com visit and download the sample code: https://codeanddeploy.com/blog/laravel/laravel-8-user-impersonation-example

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.

laravel-8-user-impersonation

laravel-8-user-impersonation

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
Enter fullscreen mode Exit fullscreen mode

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);
    }
}
Enter fullscreen mode Exit fullscreen mode

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');

Enter fullscreen mode Exit fullscreen mode

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'); 
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Take note: If you are using my previous tutorial don't forget to run the following command below:

php artisan permission:create-permission-routes
Enter fullscreen mode Exit fullscreen mode

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 this tutorial can help you. Kindly visit here https://codeanddeploy.com/blog/laravel/laravel-8-user-impersonation-example if you want to download this code.

Discussion (0)