Skip to content

Elixir Plug to easily add HTTP basic authentication to an app

License

Notifications You must be signed in to change notification settings

sendle/basic_auth

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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, "~> 1.0.0"}]
  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!

Storing credentials for deployment / testing

The above example is great to get going with basic auth, and depending on your use case, might be everything you need. Generally speaking, we don't want to store credentials in version control for security reasons.

Store credentials in config files

Instead of passing credentials into the plug directly, we can pass a use_config option to the plug to tell it we want to use some variables we've stored in config files:

  # inside router or controller file
  plug BasicAuth, Application.get_env(:the_app, :basic_auth)

And then we can setup some configuration using something like the following:

# dev.exs, test.exs
config :the_app, :basic_auth, [
  realm: "Admin Area",
  username: "sample",
  password: "sample"
]
# config/prod.secret.exs
config :the_app, :basic_auth, [
  realm: "Admin Area",
  username: System.get_env("BASIC_AUTH_USER"),
  password: System.get_env("BASIC_AUTH_PASSWORD")
]

The example above for config/prod.exs makes use of system ENV vars. You could use String objects if your config/prod.exs is outside of version control, but for environments like Heroku, it's easier to use ENV vars for storing configuration.

Testing controllers with Basic Auth

If you're storing credentials within configuration files, we can reuse them within our test files directly using snippets like Application.get_env(:basic_auth)[:username].

Update Tests to insert a basic authentication header

Any controller that makes use of basic authentication, will need an additional header injected into the connection in order for your tests to continue to work. The following is a brief snippet of how to get started. There is a more detailed blog post that explains a bit more about what needs to be done.

At the top of my controller test I have something that looks like:

@username Application.get_env(:the_app, :basic_auth)[:username]
@password Application.get_env(:the_app, :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 response(conn, 401) =~ "401 Unauthorized"
end

About

Elixir Plug to easily add HTTP basic authentication to an app

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Elixir 100.0%