Phoenix redirect takes me away from subdomain

I am working on converting an existing application to a multi-tenant one with subdomains enforcing the organization. Tenants have an “admin” panel but can also impersonate their own customers via an impersonator session.

The impersonator session takes a token (decoded with Guardian) adds information about the organization and the impersonator to the session and then redirects to the storefront.
The way the app is setup a redirect from admin to the storefront takes one from localhost:4000 to localhost:4002.

For now I’m just playing with this locally so this isn’t an infrastructure question, per se, but if I redirect from a tenant admin, say customer1.localhost:4000 I loose the subdomain going to localhost:4002. Is there something in the endpoint or a plug I could implement to enforce the subdomain while the impersonation finishes?


For reference:

The AdminApp.ImpersonatonController looks like this (modified for brevity):

 def impersonate(%Conn{} = conn, %{} = params) do

    impersonator = Guardian.Plug.current_resource(conn)
    org_id = Repo.get_org_id()

    claims = %{
      impersonator_id: impersonator.id,
      organization: org_id
    }

    {_, token, _claims} = Guardian.encode_and_sign(impersonator, claims)

    conn
    |> authorize(action: :impersonate)
    |> redirect(external: "#{url}/impersonate?token=#{token}))
  end

Then the StorefrontWeb.SessionController has this action:

 def impersonate(conn, %{"token" => impersonation_token}) do
    conn
    |> ... decode and verify token...
    |> create_impersonator_session()
  end

  defp create_impersonator_session({:ok, token, conn}) do
    organization = token["organization"]

    conn =
      conn
      |> GuardianPlug.sign_in(user)
      |> put_session(:impersonating, {token["impersonator_id"], token["user_id"]})
      |> put_session(:organization, organization)

    redirect(conn, to: successful_sign_in_redirect_path(conn, user))
  end
1 Like

The subdomain is stored in the :host key of the conn. You can set it directly. I’m not sure if there is another symptom at play here but that’s what I’ve done in the past (albeit in a toy app).

2 Likes

https://hexdocs.pm/phoenix/1.7.14/Phoenix.Controller.html#put_router_url/2

This one might also be useful.

You might also set this in your routers scope with host Phoenix.Router — Phoenix v1.7.14

Thanks everyone! Indeed host seems the way to go. In my case there was a URL helper that was part of the redirect sending it to the root domain rather than the subdomain which I should have seen; just one of those small things that tends to get overlooked.