Joken v2.0.0-rc3 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:

  • default_claims/1- [add_claim/4](#add_claim/4) ## Automatically load and generate functions (recommended) Another approach is to justuse Joken.Configin a module. This will load a signer configuration (from config.exs) and a map of [Joken.Claim](Joken.Claim.html) s. Example: defmodule MyAuth do use Joken.Config end This way, [Joken.Config](Joken.Config.html#content) 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 adduse Joken.Hooksso you can easily hook into Joken's lifecycle. ## Overriding functions All callbacks in [Joken.Config](Joken.Config.html#content) and [Joken.Hooks](Joken.Hooks.html) are overridable. This can be used for customizing the token configuration. All that is needed is to override thetoken_config/0function returning your map of binary keys to [Joken.Claim](Joken.Claim.html) 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](#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 touse Joken.Configto ease on your configuration: - default_signer: a signer configuration key in config.exs (see [Joken.Signer`](Joken.Signer.html))

Link to this section Summary

Functions

Adds the given hook to the list of hooks passed to all operations in this module

Initializes a map of Joken.Claims 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

Link to this function add_claim(config, claim_key, generate_fun \\ nil, validate_fun \\ nil, options \\ []) View Source
add_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)
Link to this macro add_hook(hook_module, options \\ []) View Source (macro)

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.

Link to this function default_claims(options \\ []) View Source
default_claims(Keyword.t()) :: Joken.token_config()

Initializes a map of Joken.Claims 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”]
  • 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

Link to this callback encode_and_sign(arg0, arg1) View Source
encode_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):

  1. The one represented by the key passed as second argument. The signer will be parsed from the configuration.
  2. If no argument was passed then we will use the one from the configuration :default_signer passed as argument for the use Joken.Config macro.
  3. If no key was passed for the use macro then we will use the one configured as :default_signer in the configuration.
Link to this callback generate_claims(extra) View Source
generate_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.

Link to this callback validate(arg0) View Source
validate(Joken.claims()) ::
  {:ok, Joken.claims()} | {:error, Joken.error_reason()}

Runs validations on the already verified token.

Link to this callback verify(arg0, arg1) View Source
verify(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):

  1. The signer in the configuration with the given key.
  2. The Joken.Signer instance passed to the method.
  3. The signer passed in the use Joken.Config through the default_signer key.
  4. 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).