Impersonate User

I’ve got a React SPA front end talking to a Phoenix JSON API. Authentication is done with Guardian, and we put a JWT in a Cookie which is then included in an Authorization header in any XHR requests.

The Guardian.Plug.VerifyHeader and Guardian.Plug.LoadResource plugs are used to load the current user.

I would like users who are system administrators to be able to impersonate any other user. I’m not really sure how to approach this however, both in the front and back end. Has anyone implemented something similar? Any general architectural suggestions?

Thanks

I have done similar stuff in Rails. I used to have a ImpersonateController which would have an action called become. This would have a before_action authenticate_admin! which would make sure that only admin users would be able to access it. And in the become action I just switched the session[:user_id] with the user whom we want to impersonate. You could do the same in Phoenix.

I ended up with this code in my controller. Happy to share tests if someone is interested. Everything else I took care of on the front end, including stopping impersonation.

This controller action is behind an api pipeline that ensures the current_user is a sysadmin.

def impersonate(conn, params) do
    current_user = Guardian.Plug.current_resource(conn)
    impersonated_user = MyApp.Repo.get!(User, params["user_id"])

    # Keep sysadmin accounts private from each other
    with {:ok, impersonated_user} <- user_not_sysadmin(impersonated_user) do
      {:ok, token, _} = Guardian.encode_and_sign(impersonated_user, :api, imp: current_user.id)
      render(conn, "impersonate.json", %{token: token, impersonated_user: impersonated_user, current_user: current_user})
    end
end

I wouldn’t mind seeing what you’ve got if you don’t mind sharing… I’m about to implement a similar feature in the next few days.