Current section

Files

Jump to
auth0_plug lib auth0_plug.ex
Raw

lib/auth0_plug.ex

defmodule Auth0Plug do
@moduledoc """
Documentation for Auth0Plug.
"""
alias JOSE.{JWK, JWT}
alias Plug.Conn
@conn_key Application.get_env(:auth0_plug, :conn_key)
@realm Application.get_env(:auth0_plug, :realm)
@return_401 Application.get_env(:auth0_plug, :return_401)
def init(options) do
options
end
def unauthorized_message do
default = "Your credentials are invalid."
message = Application.get_env(:auth0_plug, :unauthorized_message, default)
Jason.encode!(%{"message" => message})
end
@doc """
Extracts the jwt from the header, when present.
"""
def get_jwt(conn) do
conn
|> Conn.get_req_header("authorization")
|> List.to_string()
|> String.split(" ")
|> List.last()
end
def verify(token) do
result =
Application.get_env(:auth0_plug, :secret)
|> JWK.from_oct()
|> JWT.verify(token)
case result do
{true, jwt, _jws} -> {:ok, jwt}
{false, jwt, _jws} -> {:error, jwt}
{:error, e} -> {:error, e}
end
end
@doc """
Return a 401 response.
"""
def unauthorized(conn) do
if @return_401 do
conn
|> Conn.put_resp_header(
"www-authenticate",
"Bearer realm=\"#{@realm}\", error=\"invalid_token\""
)
|> Conn.put_resp_content_type("application/json")
|> Conn.send_resp(401, Auth0Plug.unauthorized_message())
|> Conn.halt()
else
conn
end
end
def put_jwt(conn, jwt) do
key_to_extract = Application.get_env(:auth0_plug, :key_to_extract)
value = Map.get(jwt, :fields)
value =
if key_to_extract do
Map.get(value, key_to_extract)
else
value
end
Conn.put_private(conn, @conn_key, value)
end
def call(conn, _options) do
token = Auth0Plug.get_jwt(conn)
case Auth0Plug.verify(token) do
{:ok, jwt} -> Auth0Plug.put_jwt(conn, jwt)
{:error, _jwt} -> Auth0Plug.unauthorized(conn)
end
end
end