There are some situations where you want to block access to an environment such as when you’re just staging a project.
For this particular case, using a custom Basic Auth Plug that’s conditional on environment variables may be all you need.
Let’s get started by create a custom plug and then “plug” it into our system.
It’s assumed that you want to restrict access to the entire application in a staging environment.
Basic Auth Plug
WEB/controllers/basic_auth.ex with this content:
(Remember to update
defmodule MyAppWeb.BasicAuth do import Plug.Conn @realm "Basic realm=\"Staging\"" def init(opts), do: opts def call(conn, correct_auth) do case get_req_header(conn, "authorization") do ["Basic " <> attempted_auth] -> verify(conn, attempted_auth, correct_auth) _ -> unauthorized(conn) end end defp verify(conn, attempted_auth, username: username, password: password) do case encode(username, password) do ^attempted_auth -> conn _ -> unauthorized(conn) end end defp encode(username, password), do: Base.encode64(username <> ":" <> password) defp unauthorized(conn) do conn |> put_resp_header("www-authenticate", @realm) |> send_resp(401, "unauthorized") |> halt() end end
Next, let’s add some simple configuration to
config :my_app, MyAppWeb.BasicAuth, username: "admin", password: "secret"
You can also use environment variables to keep these values out of your repo, but for this simple set up, let’s just keep it as is.
WEB/router.ex and add the plug to a pipeline:
pipeline :browser do ... if System.get_env("APP_DOMAIN") == "staging.myapp.com" do plug BasicAuth, Application.fetch_env!(:my_app, BasicAuth) end end
This will check for the value of
APP_DOMAIN and conditionally pipe the connection through the custom plug.
NOTE: Don’t forget to actually set
APP_DOMAIN in your staging environment.
You can optionally test the new Plug out by passing the environment variable’s expected value when you start up the Phoenix server:
$ APP_DOMAIN=staging.myapp.com mix -S phx.server
Then you should see the basic auth prompt to enter the credentials.
This was a very simple strategy for restricting access to a staging environment without adding any dependencies.
This can be expanding and improved upon in many ways but should serve as a basic starting point.