DEV Community

Alex C V
Alex C V

Posted on • Updated on

Add Basic Auth to Elixir Phoenix + Daily password

In this article we’ll learn how to add a basic auth to Elixir Phoenix Framework and how to use a password that changes every day.

This method isn’t the most secure, but it’s a good trick.

Daily password

First of all we’ll create the function to generate the daily password.

It’s something like this.


defmodule MyApp.Helpers.DailyPassword do  
  @doc """
  Generate a daily password.
  """
  def today_password do
    {year, month, day} =
      today()

    Timex.format!({year, month, day}, "{0D}{0M}{YY}")
    |> String.to_integer()
    |> Kernel.+(day * 17 - 5)
    |> Kernel.+(month * 13)
    |> Kernel.+(year * 17)
  end

  defp today, do: :calendar.local_time |> elem(0)
end
Enter fullscreen mode Exit fullscreen mode

Basic Auth Plug


defmodule MyAppWeb.BasicAuth do
  import Plug.Conn
  @realm "Basic realm=\"Staging\""

  def init(opts),
    do: opts ++ [password: MyApp.Helpers.DailyPassword.today_password() |> to_string()]

  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
    with ^attempted_auth <- encode(username, password) do
      conn
    else
      _ -> 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
Enter fullscreen mode Exit fullscreen mode

Router

Now we need to configure the basic auth in router.ex.

pipeline :auth do
  plug MyAppWeb.BasicAuth, [username: "admin"]
end
Enter fullscreen mode Exit fullscreen mode

And use auth wherever we want.

scope "/", MyAppWeb do
  pipe_through :auth

  ...
end
Enter fullscreen mode Exit fullscreen mode

Conclusion

Phoenix provides a basic auth that you can use, here the docs, but it's cool to see how we can configure our own.

Top comments (0)