Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

basvandertogt's avatar

Jetstream login as user

I want to give admins the ability to login as another user. Without Jetstream/Fority i could do it realy simple:

$user = User::find(2);
Auth::login($user);

With Jetstream/Fority this does not work: Method Illuminate\Auth\RequestGuard::login does not exist.

Tried this but it does not work either:

$user = User::find(2);
Fortify::authenticateUsing(function ($user) {
    return $user;
});
0 likes
29 replies
alqahtani's avatar

make sure to import the right one: use Illuminate\Support\Facades\Auth;

basvandertogt's avatar

@alqahtan I appreciate your help! I'm using a Livewire component. See userSwitchStart()

<?php

namespace App\Http\Livewire\Users;

use App\Models\Team;
use App\Models\User;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;
use Illuminate\Validation\Rule;
use Livewire\Component;
use Livewire\WithPagination;
use App\Http\Livewire\DataTable\WithSorting;

class Users extends Component
{
    use WithPagination, WithSorting;

    public User $user;
    public $isOpen = 0;
    public $search = [
        'firstname' => '',
        'lastname' => '',
        'email' => '',
        'team' => ''
    ];
    public $userDeletion;
    public $confirmingUserDeletion = false;
    public $sortField = 'lastname';
    public $sortDirection = 'asc';
    public $queryString = ['sortField', 'sortDirection'];

    protected function rules()
    {
        return [
            'user.firstname' => 'required',
            'user.lastname' => 'required',
            'user.email' => ['required', Rule::unique('users', 'email')->ignore($this->user->id, 'id')->whereNull('deleted_at')],
            'user.allTeams' => []
        ];
    }

    public function mount()
    {
        if (!Auth::user()->hasTeamRole(Auth::user()->currentTeam, 'admin')) {
            return abort(403);
        }
    }

    public function render()
    {
        return view('livewire.users.users', [
            'teams' => Team::pluck('name', 'id'),
            'users' => User::filter($this->search)->orderBy($this->sortField, $this->sortDirection)->paginate(25)
        ]);
    }

    public function store()
    {
        $this->validate();

        User::updateOrCreate(['id' => $this->user->id], $this->user->toArray());

        $this->dispatchBrowserEvent('banner-message', [
            'style' => 'info',
            'message' => $this->user->id ? 'Gebruiker succesvol bijgewerkt!' : 'Gebruiker succesvol toegevoegd!'
        ]);

        $this->closeModal();
        $this->resetInputFields();
    }

    public function deletingUser($id)
    {
        $this->userDeletion = User::findOrFail($id);
        $this->confirmingUserDeletion = true;
    }

    public function deleteUser($id)
    {
        User::find($id)->delete();
        $this->confirmingUserDeletion = false;
    }

    public function edit($id)
    {
        $this->user = User::findOrFail($id);
        $this->openModal();
    }

    public function create()
    {
        $this->resetInputFields();
        $this->openModal();
    }

    public function openModal()
    {
        $this->isOpen = true;
    }

    public function closeModal()
    {
        $this->isOpen = false;
        $this->resetValidation();
    }

    private function resetInputFields()
    {
        $this->user = new User();
    }

    public function sortBy($field)
    {
        if ($this->sortField === $field) {
            $this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
        } else {
            $this->sortDirection = 'asc';
        }

        $this->sortField = $field;
    }

    /**
     * User switch start
     *
     * @param User $user
     * @return RedirectResponse
     */
    public function userSwitchStart(User $user)
    {
        Session::put('orig_user', Auth::id());

//        Auth::login($user);
        Auth::guard('web')->login($user);

        $this->dispatchBrowserEvent('banner-message', [
            'style' => 'info',
            'message' => 'Je bent nu ingelogd als ' . $user->fullname
        ]);

        return redirect()->route('messages.create');
    }

    /**
     * User switch stop
     *
     * @return RedirectResponse
     */
    public function userSwitchStop()
    {
        $orig_user = Session::pull('orig_user', NULL);

        $user = User::find($orig_user);

        if (is_null($orig_user) or is_null($user)) {
            return redirect()->route('dashboard');
        }

//        Auth::login($user);
        Auth::guard('web')->login($user);

        $this->dispatchBrowserEvent('banner-message', [
            'style' => 'info',
            'message' => 'Je bent nu ingelogd als ' . $user->fullname
        ]);

        return redirect()->route('users');
    }
}
alqahtani's avatar

@basvandertogt .. okay it seems good to me. could you debug the coming $user to check is it the intended one?

public function userSwitchStart(User $user)
{
	dd($user)
	...
alqahtani's avatar

@basvandertogt I've recreated the logic on your component with Livewire, Sessions and everything .. it's working just fine 🤯

alqahtani's avatar

Here is mine if you could find a difference:

<?php

namespace App\Http\Livewire;

use App\Models\User;
use Livewire\Component;
use Laravel\Fortify\Fortify;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;

class Auther extends Component
{
    public $ider;


    public function authUsing()
    {
        Session::put('orig_user', Auth::id());
        $user = User::find($this->ider);
        Auth::guard('web')->login($user);

        $this->dispatchBrowserEvent('banner-message', [
            'style' => 'info',
            'message' => 'Authenticated using: ' . $user->name
        ]);

        return redirect()->route('dashboard');
    }

    public function endAuth()
    {
        $orig_user = Session::pull('orig_user', NULL);

        $user = User::find($orig_user);

        if (is_null($orig_user) or is_null($user)) {
            return redirect()->route('dashboard');
        }

        Auth::guard('web')->login($user);

        $this->dispatchBrowserEvent('banner-message', [
            'style' => 'info',
            'message' => 'Back to: ' . $user->name
        ]);

        return redirect()->route('dashboard');
    }


    public function render()
    {
        return view('livewire.auther');
    }
}

basvandertogt's avatar

@alqahtani Allright. i debugged and debugged but can't find it. In a split second i can see it logges in as the desired user but than i get redirected to the login page and the user is logged out. Any idea?

basvandertogt's avatar

@alqahtani Found it! My route is inside this middleware:

Route::middleware(['auth:sanctum', 'verified'])->group(function () {
    Route::get('user-switch-start/{user}', Users\Users::class)->name('users.user-switch-start');
    Route::post('user-switch-stop', Users\Users::class)->name('users.user-switch-stop');
});

When i change auth:sanctum to auth:web it's working. Is this safe?

1 like
alqahtani's avatar

@basvandertogt Well tbh I don’t know 😅 .. why not keep it as auth:sanctum and trying to change the Auth::guard('web') to Auth::guard('sanctum') ?

Ron W.'s avatar

@basvandertogt i do have the exact problem after creating a fresh project in laravel 9. In Laravel 8 that worked as expected.

Did you find a solution yet?

I've tracked it down to AuthenticateSession.php in vendor\laravel\framework\src\Illuminate\Session\Middleware

    if ($request->session()->get('password_hash_'.$this->auth->getDefaultDriver()) !== $request->user()->getAuthPassword()) {
        $this->logout($request);
    }

If i comment out $this->logout($request); then everything works. But i still don't understand why?

basvandertogt's avatar

@Ron W. No. i changed the middleware to auth:web. That works. But its not ideal.

Ron W.'s avatar

@basvandertogt Some research later i've found out that after commenting out \Illuminate\Contracts\Session\Middleware\AuthenticatesSessions::class,, in vendor\laravel\framework\src\Illuminate\Foundation\Http\kernel.php everything works as expected.

Some googlewoogle and it seems like the problem is known https://github.com/laravel/jetstream/issues/993 but in 2.7.2 still existend. So we need to get it fixed in one of the next updates

UPDATE: Some more research later i found out that you can fix it by posting the hashed user password to session so that the comparison after impersonating becomes true.

                $user = Auth::loginUsingId($request->new_user_id);
                session(['password_hash_sanctum' => $user->getAuthPassword()]);

So you don't need ot comment out any more classes and you can use auth:sanctum

lat4732's avatar

Try with using loginUsingId

Illuminate\Support\Facades\Auth::loginUsingId($user->id);
basvandertogt's avatar

@Laralex Same BadMethodCallException: Method Illuminate\Auth\RequestGuard::loginUsingId does not exist.

Snapey's avatar

This always works for me (as middleware)

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class Impersonation
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if(Auth::check() && Auth::user()->is_superAdmin && session()->has('impersonate')) {

            Auth::onceUsingID(session('impersonate'));

        }

        return $next($request);
    }
}

and then to start just put key 'impersonate' and the user's id in session, and to exit impersonation, remove the value from session

Add the middleware at the end of the web middlewares.

Sinnbeck's avatar

@Snapey Brilliant idea. Just added that to a project where I had been considering it for while. So simple. You have a tiny typo in the method name. Its onceUsingId()

Sinnbeck's avatar

@Snapey Yeah even phpstorm allows click through. But just figured it would be one of those that might break in like php 8.2 or something :)

Plytas's avatar
Plytas
Best Answer
Level 1

If anyone is still looking for a solution, this seems to work nicely

Auth::guard('web')->login($user);
Auth::guard('sanctum')->setUser($user);
4 likes

Please or to participate in this conversation.