Problem with parsed result from querystring

Phoenix/plug seems to be stripping out any + from the value of the query params.
What could be the cause of this?

# Controller function
#... 
 def token_login(conn, %{"token" => token} = params) do
    with {:ok, user_id} <- token |> Accounts.get_userid_from_token() do
      user = Accounts.get_user(user_id)

      conn
      |> Auth.login(user)
      |> redirect(to: Routes.page_path(conn, :index))
    else
      :error ->
        conn
        |> redirect(to: Routes.page_path(conn, :index))
    end
  end
#...
defmodule UiWeb.AuthControllerTest do
  use UiWeb.ConnCase

  test "GET /auth/verify", %{conn: conn} do
    conn =
      get(
        conn,
        "/auth/verify?token=9MaWkvoM1yhtmK+Ks7eevmvWreoaAqOeRqqJrgQ16ZNlYbe+odDB99oM4rDRpo+e"
      )

    %{
      query_params: %{
        "token" => token
      }
    } = conn

    assert token == "9MaWkvoM1yhtmK+Ks7eevmvWreoaAqOeRqqJrgQ16ZNlYbe+odDB99oM4rDRpo+e"
  end
end
1) test GET /auth/verify (UiWeb.AuthControllerTest)
     test/ui_web/controllers/user_controller_test.exs:4
     Assertion with == failed
     code:  assert token == "9MaWkvoM1yhtmK+Ks7eevmvWreoaAqOeRqqJrgQ16ZNlYbe+odDB99oM4rDRpo+e"
     left:  "9MaWkvoM1yhtmK Ks7eevmvWreoaAqOeRqqJrgQ16ZNlYbe odDB99oM4rDRpo e"
     right: "9MaWkvoM1yhtmK+Ks7eevmvWreoaAqOeRqqJrgQ16ZNlYbe+odDB99oM4rDRpo+e"
     stacktrace:
       test/ui_web/controllers/user_controller_test.exs:17: (test)

Phoenix assumes that the token is URI encoded and it automatically URI decodes it. For example, submitting a form with action get in HTML would URL encode everything. If you are the one generating the token, make sure to URI encode it. If not, you can access the original request_uri via conn.request_uri and parse the token from it.

5 Likes

I’using a library, so I’ll probably go for the latter suggestions. Thanks.