Current section

Files

Jump to
auth_plug lib token.ex
Raw

lib/token.ex

defmodule AuthPlug.Token do
@moduledoc """
Token module to create and validate jwt.
see https://hexdocs.pm/joken/configuration.html#module-approach
"""
use Joken.Config
@doc """
`api_key/0` retrieves the API_KEY from environment variable.
API keys are a single environment variable which is comprised of two parts.
client_id/client_secret such that splitting on the "/" (forward slash)
gives us the `client_id` and `client_secret`
example:
2cfxNaWUwJBq1F4nPndoEHZJ5YCCNq9JDNAAR/2cfxNadrhMZk3iaT1L5k6Wt67c9ScbGNPz8Bw
see: https://github.com/dwyl/auth/issues/42#issuecomment-620247243
"""
def api_key do
if not is_nil(System.get_env("DWYL_API_KEY")),
do: System.get_env("DWYL_API_KEY"),
else: System.get_env("AUTH_API_KEY")
end
@doc """
`client_id/0` returns the `client_id` (the first part of the AUTH_API_KEY)
"""
def client_id do
List.first(String.split(api_key(), "/"))
end
@doc """
`client_id/0` returns the `client_secret` (the last part of the AUTH_API_KEY)
"""
def client_secret do
List.last(String.split(api_key(), "/"))
end
@doc """
`create_signer/1` creates a signer for the given `secret` key.
It uses the HS256 (HMAC with SHA-256) to generate the signature.
if you're wondering what "HS256" is, read:
community.auth0.com/t/jwt-signing-algorithms-rs256-vs-hs256/7720
"""
def create_signer(secret) do
Joken.Signer.create("HS256", secret)
end
@impl true
def token_config do
# ~ 1 year in seconds
default_claims(default_exp: 31_537_000)
end
@doc """
`generate_jwt!/1` invokes `Joken.generate_and_sign/3`
claims are the data to be signed.
Throws an error if anyting in the claims is invalid.
"""
def generate_jwt!(claims) do
generate_jwt!(claims, client_secret())
end
@doc """
`generate_jwt!/2` invokes `Joken.generate_and_sign/3`
`claims` are the data to be signed and `secret` is the secret key.
"""
def generate_jwt!(claims, secret) do
signer = create_signer(secret)
{:ok, token, _claims} =
token_config()
|> Joken.generate_and_sign(claims, signer)
token
end
@doc """
`verify_jwt/1` verifies the given JWT and returns {:ok, claims}
where the claims are the original data that were signed.
"""
def verify_jwt(token) do
verify_jwt(token, client_secret())
end
@doc """
`verify_jwt/2` verifies the given JWT and secret.
Returns {:ok, claims} where the claims are the original data that were signed.
"""
def verify_jwt(token, secret) do
signer = create_signer(secret)
token_config()
|> Joken.verify_and_validate(token, signer)
end
@doc """
`verify_jwt!/1` verifies the given JWT and returns claims
where the claims are the original data that were signed.
"""
def verify_jwt!(token) do
verify_jwt!(token, client_secret())
end
@doc """
`verify_jwt!/2` verifies the given JWT and returns claims
where the `token` is the JWT that was signed `secret` is the secret key.
Returns `claims` the original claims contained in the JWT.
"""
def verify_jwt!(token, secret) do
signer = create_signer(secret)
{:ok, claims} =
token_config()
|> Joken.verify_and_validate(token, signer)
claims
end
end