Current section
Files
Jump to
Current section
Files
lib/authtoken.ex
defmodule AuthToken do
@moduledoc """
Simplified encrypted authentication tokens using JWE.
Configuration needed:
config :authtoken,
token_key: PUT_KEY_HERE
Generate a token for your user after successful authentication like this:
## Examples
token_content = %{userid: user.id}
token = AuthToken.generate_token(token_content)
"""
@doc """
Generates an encrypted auth token.
Contains an encoded version of the provided map, plus a timestamp for timeout.
"""
@spec generate_token(map) :: String.t
def generate_token(user_data) do
token_content = %{ct: DateTime.to_unix(DateTime.utc_now())} |> Enum.into(user_data)
jwt = JOSE.JWT.encrypt(get_jwk(), get_jwe(), token_content) |> JOSE.JWE.compact |> elem(1)
# Remove JWT header
Regex.run(~r/.+?\.(.+)/, jwt) |> List.last
end
@doc """
Generate a random key for AES128
## Examples
iex> AuthToken.generate_key()
{:ok, <<153, 67, 252, 211, 199, 186, 212, 114, 109, 99, 222, 205, 31, 26, 100, 253>>}
"""
@spec generate_key() :: {:ok, binary}
def generate_key do
{:ok, :crypto.strong_rand_bytes(16)}
end
@doc """
Decrypt an authentication token
Format "bearer: tokengoeshere" will be accepted and parsed out.
"""
@spec decrypt_token(String.t) :: {:ok, String.t} | {:error}
def decrypt_token(headless_token) when is_binary(headless_token) do
header = get_jwe() |> JOSE.Poison.lexical_encode! |> :base64url.encode
auth_token = header <> "." <> headless_token
try do
%{fields: token} = JOSE.JWT.decrypt(get_jwk(), auth_token) |> elem(1)
{:ok, token}
rescue
_ -> {:error}
end
end
@spec decrypt_token(nil) :: {:error}
def decrypt_token(_) do
{:error}
end
@spec get_jwe() :: %{alg: String.t, enc: String.t, typ: String.t}
defp get_jwe do
%{ "alg" => "dir", "enc" => "A128GCM", "typ" => "JWT" }
end
@spec get_jwk() :: %JOSE.JWK{}
defp get_jwk do
get_config(:token_key)
|> JOSE.JWK.from_oct()
end
@spec get_config(atom) :: %{}
def get_config(atom) do
content = Application.get_env(:authtoken, atom)
unless content, do: raise "No AuthToken configuration set for " <> atom
content
end
end