How to protect certain static routes?

Hello : )

would anyone be able to tell me how to protect certain static routes? Why? - plug.static does so much under the hood, I would like to utilise its goodness such as caching and concurrent reads to serve js files from protected routes.

Liam.

Depends on what kind of “protection” you want.

Does your app have any existing protected routes?

You could have HTTP Basic Auth, phx.gen.auth email+password accounts, integration with external services for auth, …

:wave:

You can add a custom plug in your pipeline that would wrap Plug.Static and implement custom protection logic there.

# assuming a Phoenix project
defmodule MyAppWeb.Endpoint do
  # ...
  # private static files
  plug :private_static, Plug.Static.init(at: "/private", from: :my_app)
  # public static files
  plug Plug.Static, at: "/", from: :my_app, only: MyAppWeb.static_paths()
  # ...

  defp private_static(%Plug.Conn{path_info: ["private" | _]} = conn, plug_static_opts) do
    if private_static_allowed?(conn) do
      # NOTE: if it doesn't match any files, then it would pass-through to router
      Plug.Static.call(conn, plug_static_opts)
    else
      conn |> send_resp(403, "forbidden or whatev") |> halt()
    end
  end

  # pass-through non /private/** routes
  defp private_static(conn, _opts), do: conn

  defp private_static_allowed?(conn) do
    # your custom logic
    true
  end
end

And you can also do it in the router. It might be even easier that way.

3 Likes

I would be using phx Auth :blush:

Thanks for your example!! :blush:

In that case combine the plugs generated by phx.gen.auth (mix phx.gen.auth — Phoenix v1.7.18) with the example from @ruslandoga to gate access to Plug.Static.

His example is great, as it leaves space for your own custom logic.

1 Like