Joken v2.2.0 Joken.Config behaviour View Source
Main entry point for configuring Joken. This module has two approaches:
Creating a map of Joken.Claim
s
If you prefer to avoid using macros, you can create your configuration manually. Joken's
configuration is just a map with keys being binaries (the claim name) and the value an
instance of Joken.Claim
.
Example:
%{"exp" => %Joken.Claim{
generate: fn -> Joken.Config.current_time() + (2 * 60 * 60) end,
validate: fn val, _claims, _context -> val < Joken.Config.current_time() end
}}
Since this is cumbersome and error prone, you can use this module with a more fluent API, see:
Automatically load and generate functions (recommended)
Another approach is to just use Joken.Config
in a module. This will load a signer configuration
(from config.exs) and a map of Joken.Claim
s.
Example:
defmodule MyAuth do
use Joken.Config
end
This way, Joken.Config
will implement some functions for you:
generate_claims/1
: generates dynamic claims and adds them to the passed map.encode_and_sign/2
: takes a map of claims, encodes it to JSON and signs it.verify/2
: check for token tampering using a signer.validate/1
: takes a claim map and a configuration to run validations.generate_and_sign/2
: combines generation and signing.verify_and_validate/2
: combines verification and validation.token_config/0
: where you customize token generation and validation.
It will also add use Joken.Hooks
so you can easily hook into Joken's lifecycle.
Overriding functions
All callbacks in Joken.Config
and Joken.Hooks
are overridable. This can be used for
customizing the token configuration. All that is needed is to override the token_config/0
function returning your map of binary keys to Joken.Claim
structs. Example from the
benchmark suite:
defmodule MyCustomClaimsAuth do
use Joken.Config
@impl true
def token_config do
%{} # empty claim map
|> add_claim("name", fn -> "John Doe" end, &(&1 == "John Doe"))
|> add_claim("test", fn -> true end, &(&1 == true))
|> add_claim("age", fn -> 666 end, &(&1 > 18))
|> add_claim("simple time test", fn -> 1 end, &(Joken.current_time() > &1))
end
end
Customizing default generated claims
The default claims generation is just a bypass call to default_claims/1
. If one would
like to customize it, then we need only to override the token_config function:
defmodule MyCustomDefaults do
use Joken.Config
def token_config, do: default_claims(default_exp: 60 * 60) # 1 hour
end
Options
You can pass some options to use Joken.Config
to ease on your configuration:
- default_signer: a signer configuration key in config.exs (see
Joken.Signer
)
Link to this section Summary
Functions
Adds a Joken.Claim
with the given claim key to a map.
Adds the given hook to the list of hooks passed to all operations in this module.
Initializes a map of Joken.Claim
s with "exp", "iat", "nbf", "iss", "aud" and "jti".
Callbacks
Encodes the given map of claims to JSON and signs it.
Generates a JWT claim set.
Defines the Joken.token_config/0
used for all the operations in this module.
Runs validations on the already verified token.
Verifies token's signature using a Joken.Signer.
Link to this section Functions
add_claim(config, claim_key, generate_fun \\ nil, validate_fun \\ nil, options \\ [])
View Sourceadd_claim( Joken.token_config(), binary(), (... -> any()) | nil, (... -> any()) | nil, Keyword.t() ) :: Joken.token_config()
Adds a Joken.Claim
with the given claim key to a map.
This is a convenience builder function. It does exactly what this example does:
iex> config = %{}
iex> generate_fun = fn -> "Hi" end
iex> validate_fun = &(&1 =~ "Hi")
iex> claim = %Joken.Claims{generate: generate_fun, validate: validate_fun}
iex> config = Map.put(config, "claim key", claim)
Adds the given hook to the list of hooks passed to all operations in this module.
When using use Joken.Config
in a module, this already adds the module as a hook.
So, if you want to only override one lifecycle callback, you can simply override it
on the module that uses Joken.Config
.
default_claims(options \\ [])
View Sourcedefault_claims(Keyword.t()) :: Joken.token_config()
Initializes a map of Joken.Claim
s with "exp", "iat", "nbf", "iss", "aud" and "jti".
Default parameters can be customized with options:
- skip: do not include claims in this list. Ex: [:iss, :aud]
- default_exp: changes the default expiration of the token. Default is 2 hours
- iss: changes the issuer claim. Default is "Joken"
- aud: changes the audience claim. Default is "Joken"
Link to this section Callbacks
encode_and_sign(arg1, arg2)
View Sourceencode_and_sign(Joken.claims(), Joken.signer_arg() | nil) :: {:ok, Joken.bearer_token(), Joken.claims()} | {:error, Joken.error_reason()}
Encodes the given map of claims to JSON and signs it.
The signer used will be (in order of preference):
- The one represented by the key passed as second argument. The signer will be parsed from the configuration.
- If no argument was passed then we will use the one from the configuration
:default_signer
passed as argument for theuse Joken.Config
macro. - If no key was passed for the use macro then we will use the one configured as
:default_signer
in the configuration.
generate_claims(extra)
View Sourcegenerate_claims(extra :: Joken.claims()) :: {:ok, Joken.claims()} | {:error, Joken.error_reason()}
Generates a JWT claim set.
Extra claims must be a map with keys as binaries. Ex: %{"sub" => "some@one.com"}
Defines the Joken.token_config/0
used for all the operations in this module.
The default implementation is just a bypass call to default_claims/1
.
validate(arg1)
View Sourcevalidate(Joken.claims()) :: {:ok, Joken.claims()} | {:error, Joken.error_reason()}
Runs validations on the already verified token.
verify(arg1, arg2)
View Sourceverify(Joken.bearer_token(), Joken.signer_arg() | nil) :: {:ok, Joken.claims()} | {:error, Joken.error_reason()}
Verifies token's signature using a Joken.Signer.
The signer used is (in order of precedence):
- The signer in the configuration with the given
key
. - The
Joken.Signer
instance passed to the method. - The signer passed in the
use Joken.Config
through thedefault_signer
key. - The default signer in configuration (the one with the key
default_signer
).
It returns either:
{:ok, claims_map}
where claims_map is the token's claims.{:error, [message: message, claim: key, claim_val: claim_value]}
where message can be used on the frontend (it does not contain which claim nor which value failed).