Guardian v1.0.0-beta.0 Guardian behaviour View Source
Guardian provides a singular interface for authentication in Elixir applications
that is token
based.
Tokens should be:
- tamper proof
- include a payload (claims)
JWT tokens (the default) fit this description.
When using Guardian, you’ll need an implementation module.
defmodule MyApp.Guardian do
use Guardian, otp_app: :my_app
def subject_for_token(resource, _claims), do: {:ok, to_string(resource.id)}
def resource_from_claims(claims) do
find_me_a_resource(claims["sub"]) # {:ok, resource} or {:error, reason}
end
end
This module is what you will use to interact with tokens in your application.
When you use
Guardian, the :otp_app
option is required.
Any other option provided will be merged with the configuration in the config
files.
It contains some generated functions, and some callbacks
Generated function
default_token_type()
Overridable.
Provides the default token type for the token - "access"
Token types allow a developer to mark a token as having a particular purpose. Different types of tokens can then be used specifically in your app.
Types may includes (but are not limited to):
"access"
"refresh"
Access tokens should be short lived and are used to access resources on your API. Refresh tokens should be longer lived and whose only purpose is to exchange for a shorter lived access token.
To specify the type of token, use the :token_type
option in
the encode_and_sign
function.
Token type is encoded into the token in the "typ"
field.
Return String.
peek(token)
Inspect a tokens payload. Note that this function does no verification.
Return - A map including the :claims
key
config()
, config(key, default \ nil)
Without argument, config
will return the full configuration Keyword list.
When given a key
and optionally a default, will fetch a resolved value
contained in the key.
See Guardian.Config.resolve_value
encode_and_sign(resource, claims \ %{}, opts \ [])
Creates a signed token.
Arguments:
resource
- The resource to represent in the token (i.e. the user)claims
- Any custom claims that you want to use in your tokenopts
- Options for the token module and callbacks
For more information on options see the documentation for your Token Module.
# Provide a token using the defaults including the default_token_type
{:ok, token, full_claims} = MyApp.Guardian.encode_and_sign(user)
# Provide a token including custom claims
{:ok, token, full_claims} = MyApp.Guardian.encode_and_sign(user, %{some: "claim"})
# Provide a token including custom claims and a different token type/ttl
{:ok, token, full_claims} =
MyApp.Guardian.encode_and_sign(user, %{some: "claim"}, token_type: "refresh" ttl: {4, :weeks})
The encode_and_sign
function calls a number of callbacks on
your implementation module. See Guardian.encode_and_sign
decode_and_verify(token, claims_to_check \ %{}, opts \ [])
Decodes a token and verifies the claims are valid.
Arguments:
token
- The token to decodeclaims_to_check
- A map of the literal claims that should be matched. If any of the claims do not literally match verification failsopts
- The options to pass to the token module and callbacks
Callbacks:
decode_and_verify
calls a number of callbacks on your implementation module,
See Guardian.decode_and_verify
# Decode and verify using the defaults
{:ok, claims} = MyApp.Guardian.decode_and_verify(token)
# Decode and verify with literal claims check.
# If the cliams int he token do not match those given verification will fail
{:ok, claims} = MyApp.Guardian.decode_and_verify(token, %{match: "claim"})
# Decode and verify with literal claims check and options.
# Options are passed to your Token Module and callbacks
{:ok, claims} = MyApp.Guardian.decode_and_verify(token, %{match: "claim"}, some: "secret")
revoke(token, opts \ [])
Revoke a token.
Note: this is entirely dependant on your Token Module and implementation callbacks.
{:ok, claims} = MyApp.Guardian.revoke(token, some: "option")
refresh(token, opts \ [])
Refreshes the time on a token. This is used to re-issue a token with essentially the same claims but with a different expiry.
Tokens are verified before performing the refresh to ensure only valid tokens may be refreshed.
Arguments:
token
- The old token to refreshopts
- Options to pass to the Implementation Module and callbacks
Options:
:ttl
- The new ttl. If not specified the default will be used.
{:ok, {old_token, old_claims}, {new_token, new_claims}} =
MyApp.Guardian.refresh(old_token, ttl: {1, :hour})
See Guardian.refresh
exchange(old_token, from_type, to_type, options)
Exchanges one token for another of a different type.
Especially useful to trade in a refresh
token for an access
one.
Tokens are verified before performing the exchange to ensure that only valid tokens may be exchanged.
Arguments:
old_token
- The existing token you wish to exchange.from_type
- The type the old token must be. Can be given a list of types.to_type
- The new type of token that you want back.options
- The options to pass to the token module and callbacks.
Options:
Options may be used by your token module or callbacks.
ttl
- The ttl for the new token
See Guardian.exchange
Link to this section Summary
Functions
Decodes a token using the configuration of the implementation module This will, using that configuration delegate to the token module
Creates a signed token for a resource. The actual encoding depends on the implementation module which should be referenced for specifics
Exchanges one token for another with different token types
Returns an inspection of the token (at least claims) without any verification. This should not be relied on since there is no verification
Refreshes a token keeping all main claims intact
Fetch the resource and claims directly from a token
Called to revoke a token
Converts keys in a map or list of maps to strings
Provides the current system time in seconds
Callbacks
An optional callback invoked after the token has been generated and signed
An optional callback invoked after sign in has been called
An optional callback invoked before sign out has happened
An optional callback that allows the claims to be modified while they’re being built. This is useful to hook into the encoding lifecycle
An optional callback invoked when a token is exchanged
An optional callback invoked when a token is refreshed
An optional callback invoked when a token is revoked
An optional callback invoked after the claims have been validated
Fetches the resource that is represented by claims
Fetches the subject for a token for the provided resource and claims The subject should be a short identifier that can be used to identify the resource
An optional callback to add custom verification to claims when decoding a token
Link to this section Types
Link to this section Functions
decode_and_verify(module, Guardian.Token.token, Guardian.Token.claims, options) :: {:ok, Guardian.Token.claims} | {:error, any}
Decodes a token using the configuration of the implementation module This will, using that configuration delegate to the token module.
Once the token module has decoded the token, your implementation module
has an opportunity to further verify the claims contained in the token
using the verify_claims
callback.
Lifecycle
Once called, a number of callbacks will be invoked on the implementation module
verify_claims
- Add your own custom claim verification. An error will mean the claims are not validon_verify
- After a successful verification this function is called
Options
The options will be passed through to the implementation / token modules and the appropriate callbacks. See the documentation for your implementation / token modules for more information on which options are available.
encode_and_sign(module, any, Guardian.Token.claims, options) :: {:ok, Guardian.Token.token, Guardian.Token.claims} | {:error, any}
Creates a signed token for a resource. The actual encoding depends on the implementation module which should be referenced for specifics
Lifecycle
Once called, a number of callbacks will be invoked on the implementation module
subject_for_token
- gets the subject from the resourcebuild_claims
- Once the implementation module has built it’s default claims for custom claim buildingafter_encode_and_sign
Options
The options will be passed through to the implementation / token modules and the appropriate callbacks.
ttl
- How long to keep the token alive for. If not included the default will be used.token_type
- The type of token to generate if different from the default
The ttl
option should take {integer, unit}
where unit is one of:
:second
|:seconds
:minute
|:minutes
:hour
|:hours
:week
|:weeks
See the documentation for your implementation / token module for more information on which options are available for your implementation / token module.
exchange(module, Guardian.Token.token, String.t | [String.t, ...], String.t, options) :: {:ok, {Guardian.Token.token, Guardian.Token.claims}, {Guardian.Token.token, Guardian.Token.claims}} | {:error, any}
Exchanges one token for another with different token types
The token is first decoded and verified to ensure that there is no escalation Of privileges.
Tokens must have their type included in the from_type
argument.
Lifecycle
The token module will exchange the token then on the implementation module
on_exchange
- will be invoked after the exchange happens
Options
All options are passed through all calls to the token module and appropriate callbacks
peek(module, Guardian.Token.token) :: %{claims: map}
Returns an inspection of the token (at least claims) without any verification. This should not be relied on since there is no verification
The implementation is provided by the implementation module specified. See the documentation for your implementation / token module for full details
refresh(module, Guardian.Token.token, options) :: {:ok, {Guardian.Token.token, Guardian.Token.claims}, {Guardian.Token.token, Guardian.Token.claims}} | {:error, any}
Refreshes a token keeping all main claims intact.
Options
ttl
- How long to keep the token alive for. If not included the default will be used.
The ttl
option should take {integer, unit}
where unit is one of:
:second
|:seconds
:minute
|:minutes
:hour
|:hours
:week
|:weeks
See TokenModule documentation for your token module for other options.
resource_from_token(mod :: module, token :: Guardian.Token.token, claims_to_check :: Guardian.Token.claims | nil, opts :: options) :: {:ok, Guardian.Token.resource, Guardian.Token.claims}
Fetch the resource and claims directly from a token.
This is a convenience function that first decodes the token using decode_and_verify/4
and then loads the resource.
revoke(module, Guardian.Token.token, options) :: {:ok, Guardian.Token.claims} | {:error, any}
Called to revoke a token.
Note: This is entirely dependant on the token module and callbacks.
Lifecycle
<TokenModule>.revoke
<ImplModule>.on_revoke
Options
The options are passed through to the TokenModule and callback so check the documentation for your TokenModule
stringify_keys(map | list | any) :: map | list | any
Converts keys in a map or list of maps to strings
Provides the current system time in seconds
Link to this section Callbacks
after_encode_and_sign(resource :: any, claims :: Guardian.Token.claims, token :: Guardian.Token.token, options :: options) :: {:ok, Guardian.Token.token} | {:error, atom}
An optional callback invoked after the token has been generated and signed.
after_sign_in(conn :: Plug.Conn.t, resource :: any, token :: Guardian.Token.token, claims :: Guardian.Token.claims, options :: options) :: {:ok, Plug.Conn.t} | {:error, atom}
An optional callback invoked after sign in has been called
By returning an error the sign in will be halted
- Note that if you return an error, a token still may have been generated
before_sign_out(conn :: Plug.Conn.t, location :: atom | nil, options :: options) :: {:ok, Plug.Conn.t} | {:error, atom}
An optional callback invoked before sign out has happened
build_claims(claims :: Guardian.Token.claims, resource :: Guardian.Token.resource, opts :: options) :: {:ok, Guardian.Token.claims} | {:error, atom}
An optional callback that allows the claims to be modified while they’re being built. This is useful to hook into the encoding lifecycle
on_exchange(old_token_and_claims :: {Guardian.Token.token, Guardian.Token.claims}, new_token_and_claims :: {Guardian.Token.token, Guardian.Token.claims}, options :: options) :: {:ok, {Guardian.Token.token, Guardian.Token.claims}, {Guardian.Token.token, Guardian.Token.claims}} | {:error, any}
An optional callback invoked when a token is exchanged
on_refresh(old_token_and_claims :: {Guardian.Token.token, Guardian.Token.claims}, new_token_and_claims :: {Guardian.Token.token, Guardian.Token.claims}, options :: options) :: {:ok, {Guardian.Token.token, Guardian.Token.claims}, {Guardian.Token.token, Guardian.Token.claims}} | {:error, any}
An optional callback invoked when a token is refreshed
on_revoke(claims :: Guardian.Token.claims, token :: Guardian.Token.token, options :: options) :: {:ok, Guardian.Token.claims} | {:error, any}
An optional callback invoked when a token is revoked
on_verify(claims :: Guardian.Token.claims, token :: Guardian.Token.token, options :: options) :: {:ok, Guardian.Token.claims} | {:error, any}
An optional callback invoked after the claims have been validated
resource_from_claims(claims :: Guardian.Token.claims) :: {:ok, Guardian.Token.resource} | {:error, atom}
Fetches the resource that is represented by claims.
For JWT this would normally be found in the sub
field
subject_for_token(resource :: Guardian.Token.resource, claims :: Guardian.Token.claims) :: {:ok, String.t} | {:error, atom}
Fetches the subject for a token for the provided resource and claims The subject should be a short identifier that can be used to identify the resource
verify_claims(claims :: Guardian.Token.claims, options :: options) :: {:ok, Guardian.Token.claims} | {:error, atom}
An optional callback to add custom verification to claims when decoding a token
Returning {:ok, claims} will allow the decoding to continue Returning {:error, reason} will stop the decoding and return the error