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
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
Router
Now we need to configure the basic auth in router.ex.
pipeline :auth do
plug MyAppWeb.BasicAuth, [username: "admin"]
end
And use auth wherever we want.
scope "/", MyAppWeb do
pipe_through :auth
...
end
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)