Packages

35 built-in plugins for the Hibana web framework: JWT, OAuth, CORS, rate limiting, GraphQL, admin dashboard, i18n, and more.

Current section

Files

Jump to
hibana_plugins lib hibana plugins auth.ex
Raw

lib/hibana/plugins/auth.ex

defmodule Hibana.Plugins.Auth do
@moduledoc """
HTTP Basic authentication plugin.
## Features
- RFC 7617 compliant Basic Auth
- Customizable realm name
- Pluggable validator function
- Automatic 401 response with WWW-Authenticate header
## Usage
# Basic usage with default realm
plug Hibana.Plugins.Auth
# With custom realm
plug Hibana.Plugins.Auth, realm: "Admin Area"
# With custom validator
plug Hibana.Plugins.Auth,
validator: fn username, password ->
username == "admin" && password == "secret"
end
## Options
- `:realm` - Authentication realm name (default: `"Restricted"`)
- `:validator` - Custom validation function (default: always returns `false`)
## Validator Function
The validator receives username and password:
validator = fn username, password ->
# Check against database, LDAP, etc.
username == "admin" && password == "secret"
end
## Conn Assignments
On successful authentication:
conn.assigns.current_user # => "username"
## Response
On failed authentication:
HTTP 401 Unauthorized
WWW-Authenticate: Basic realm="Protected Area"
"""
use Hibana.Plugin
import Plug.Conn
@impl true
def init(opts) do
%{
realm: Keyword.get(opts, :realm, "Restricted"),
validator: Keyword.get(opts, :validator, &default_validator/2)
}
end
@impl true
def call(conn, %{realm: realm, validator: validator}) do
case get_req_header(conn, "authorization") do
["Basic " <> encoded | _] ->
case Base.decode64(encoded) do
{:ok, decoded} ->
case String.split(decoded, ":", parts: 2) do
[username, password] ->
if validator.(username, password) do
assign(conn, :current_user, username)
else
unauthorized(conn, realm)
end
_ ->
unauthorized(conn, realm)
end
_ ->
unauthorized(conn, realm)
end
_ ->
unauthorized(conn, realm)
end
end
defp default_validator(_username, _password), do: false
defp unauthorized(conn, realm) do
conn
|> put_resp_header("www-authenticate", "Basic realm=\"#{realm}\"")
|> send_resp(401, "Unauthorized")
|> halt()
end
end