Packages
joken
1.1.1
2.6.2
2.6.1
2.6.0
2.5.0
2.4.1
2.4.0
2.3.0
2.2.0
2.1.0
2.0.1
2.0.0
2.0.0-rc3
2.0.0-rc2
2.0.0-rc1
2.0.0-rc0
1.5.0
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.2
1.2.1
1.2.0
1.1.1
1.1.0
1.0.1
1.0.0
0.16.1
0.16.0
0.15.0
0.14.1
0.14.0
0.13.1
0.13.0
0.12.0
0.11.0
0.10.1
0.10.0
0.8.1
0.8.0
0.7.0
0.6.2
0.6.1
0.6.0
0.5.0
0.1.0
JWT (JSON Web Token) library for Elixir.
Current section
Files
Jump to
Current section
Files
README.md
# Joken [](http://hexdocs.pm/joken/) [](https://hex.pm/packages/joken) [](https://travis-ci.org/bryanjos/joken)
[Documentation](http://hexdocs.pm/joken/)
A JSON Web Token (JWT) Library
The goal of this library is to provide a convienent way to create, sign, verify, and validate JWTs while allowing the flexibility to customize each step along the way. This library also includes a Plug for checking tokens as well.
Supports the following algorithms:
* ES256
* ES384
* ES512
* HS256
* HS384
* HS512
* PS256 <sup>[1](#footnote-1)</sup>
* PS384 <sup>[1](#footnote-1)</sup>
* PS512 <sup>[1](#footnote-1)</sup>
* RS256
* RS384
* RS512
* Ed25519
* Ed25519ph
* Ed448ph
* Ed448
<sup><a name="footnote-1">1</a></sup> Implemented mostly in pure Erlang. May be less performant than other supported signature algorithms. See [jose JWS algorithm support](https://github.com/potatosalad/erlang-jose#json-web-signature-jws-rfc-7515) for more information.
Joken allows you to use any claims you wish, but has convenience methods for the claims listed in the specification. These claims are listed below:
* **exp**: Expiration
* **nbf**: Not Before
* **aud**: Audience
* **iss**: Issuer
* **sub**: Subject
* **iat**: Issued At
* **jti**: JSON Token ID
For a more in depth description of each claim, please see the reference specification [here](https://tools.ietf.org/html/rfc7519).
## Usage:
All you need to generate a token is a `Joken.Token` struct with proper values.
There you can set:
- json_module: choose your JSON library (currently supports Poison | JSX)
- signer: a map that tells the underlying system how to sign and verify your
tokens
- validations: a map of claims keys to function validations
- claims: the map of values you want encoded in a token
- claims_generation: a map of functions called when signing to generate dynamic values
- token: the compact representation of a JWT token
- error: message indicating why a sign/verify operation failed
To help you fill that configuration struct properly, use the functions in the `Joken` module.
Joken allows for customization of tokens, but also provides some defaults.
To create a token with default generator for claims `exp`, `iaf`, and `nbf`, and to use Poison as the json serializer:
```elixir
import Joken
my_token = token
|> with_signer(hs256("my_secret"))
```
To create a function with an inital map of claims:
```elixir
import Joken
my_token = %{user_id: 1}
|> token
|> with_signer(hs256("my_secret"))
```
Here is an example of adding a custom validator for the claim:
```elixir
import Joken
my_token = %{user_id: 1}
|> token
|> with_validation("user_id", &(&1 == 1))
```
To sign a token, use the `sign` function. The `get_compact` function will return the token in its binary form:
```elixir
import Joken
my_token = %{user_id: 1}
|> token
|> with_validation("user_id", &(&1 == 1))
|> with_signer(hs256("my_secret"))
|> sign
|> get_compact
```
Verifying a token works in the same way. First, create a token using the compact form and verify it. `verify` will return the `Joken.Token` struct with the `claims` property filled with the claims from the token if verified. Otherwise, the `error` property will have the error:
```elixir
import Joken
my_verified_token = "some_token"
|> token
|> with_validation("user_id", &(&1 == 1))
|> with_signer(hs256("my_secret"))
|> verify
```
There are other options and helper functions available. See the docs of the `Joken` module for a complete documentation.
## Plug:
Joken also comes with a Plug for verifying JWTs in web applications.
There are two possible scenarios:
1. Same configuration for all routes
2. Per route configuration
In the first scenario just add this plug before the dispatch plug.
```elixir
defmodule MyRouter do
use Plug.Router
plug Joken.Plug, on_verifying: &MyRouter.verify_function/0
plug :match
plug :dispatch
post "/user" do
# will only execute here if token is present and valid
end
match _ do
# will only execute here if token is present and valid
end
end
```
In the second scenario, you will need at least plug ~> 0.14 in your deps.
Then you must plug this AFTER :match and BEFORE :dispatch.
```elixir
defmodule MyRouter do
use Plug.Router
# route options
@skip_token_verification %{joken_skip: true}
plug :match
plug Joken.Plug, on_verifying: &MyRouter.verify_function/0
plug :dispatch
post "/user" do
# will only execute here if token is present and valid
end
# see options section below
match _, private: @skip_token_verification do
# will NOT try to validate a token
end
end
```
### Options
This plug accepts the following options in its initialization:
- `on_verifying`: a function used to verify the token. Must return a Token
- `on_error` (optional): a function that accepts `conn` and `message` as parameters. Must
return a tuple containing the conn and a binary representing the 401 response. If it's a map,
it's turned into json, otherwise, it is returned as is.
When using this with per route options you must pass a private map of options
to the route. The keys that Joken will look for in that map are:
- `joken_skip`: skips token validation. true or false
- `joken_on_verifying`: Same as `on_verifying` above. Overrides `on_verifying` if defined on the Plug
- `joken_on_error`: Same as `on_error` above. Overrides `on_error` if defined on the Plug
### EdDSA
Native C support for Ed25519 and Ed25519ph can be provided by the libsodium asynchronous port driver by adding it as a dependency to a project's Mix file:
```elixir
defp deps do
[
{:joken, "~> 1.1"},
{:libsodium, "~> 0.0.2"}
]
end
```
While there isn't native C support for Ed448 and Ed448ph yet, there is a notable performance improvement by using a native C driver the SHA-3 related functions used by these signature algorithms by adding the [keccakf1600](https://github.com/potatosalad/erlang-keccakf1600) asynchronous port driver as a dependency to a project's Mix file:
```elixir
defp deps do
[
{:joken, "~> 1.1"},
{:keccakf1600, "~> 0.0.1"}
]
end
```