BasicAuth
This is an Elixir Plug for adding basic authentication into an application.
How to use
Add the package as a dependency in your Elixir project using something along the lines of:
defp deps do
[{:basic_auth, ">= 0.0.1"}]
end
Add into the top of a controller, or into a router pipeline a plug declaration like:
plug BasicAuth, realm: "Admin Area", username: "admin", password: "secret"
Easy as that!
Testing controllers with Basic Auth
This is still an evolving process for me, but my current approach is to keep the basic auth credentials stored as environment variables, and reference these variables in both the plug declaration, and in the tests.
Store credentials in config
So, similar to the above example, we can set the plug config to look like:
plug BasicAuth, realm: "Admin Area",
username: Application.get_env(:fakebook, :basic_auth)[:username],
password: Application.get_env(:fakebook, :basic_auth)[:password]
And we can then fetch the username and password from configuration files. This has the advantage of not hardcoding production config into our codebase:
# dev.exs, test.exs
config :my_application_name, :basic_auth,
username: "admin",
password: "secret"
Update Tests to insert a basic authentication header
At the top of my controller I have something that looks like:
@username Application.get_env(:fakebook, :basic_auth)[:username]
@password Application.get_env(:fakebook, :basic_auth)[:password]
defp using_basic_auth(conn, username, password) do
header_content = "Basic " <> Base.encode64("#{username}:#{password}")
conn |> put_req_header("authorization", header_content)
end
Then for any tests, I can simply pipe in this helper method to the connection process:
test "GET / successfully renders when basic auth credentials supplied" do
conn = conn()
|> using_basic_auth(@username, @password)
|> get("/admin/users")
assert html_response(conn, 200) =~ "Users"
end
And a test case without basic auth for completeness:
test "GET / without basic auth credentials prevents access" do
conn = conn()
|> get("/admin/users")
assert html_response(conn, 401) =~ "401 Unauthorized"
end