bnchrch / auth0_jwks

πŸ”Œ An Auth0 plug for Elixir meant to help you decode and user Auth0 JWKs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Auth0 JWK plug

This is an Elixir plug meant to make validating Auth0 tokens and creating users in your API as painless as possible.

How to use

Installation

If available in Hex, the package can be installed by adding auth0_jwks to your list of dependencies in mix.exs:

def deps do
  [
    {:auth0_jwks, "~> 0.2.0"}
  ]
end

Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/auth0_jwks.

Using the library

1. Add your Auth0 config

# config.exs
config :auth0_jwks, iss: System.get_env("AUTH0_DOMAIN"),
                    aud: System.get_env("AUTH0_AUDIENCE")
# .env.example

export AUTH0_DOMAIN="https://{your_app_name}.auth0.com/"

# Note this is the Identifier field found on the config of your custom API in the auth0 dashboard
# Mine was `https://{your_app_name}.auth0.com/api/v2/` yours could be `fuzzy sock 5`
export AUTH0_AUDIENCE="{your_custom_api_identified}"

2. Start your Auth0 Strategy

# application.ex
defmodule YourApp.Application do

  use Application

  def start(_type, _args) do
    children = [
      # ...
      Auth0Jwks.Strategy
    ]

    # ...
  end
end

3. Adding the plugs

There exist two plugs:

1. ValidateToken

This is used to ensure the given token is valid against Auth0's public jwks and attaches the resulet to the connection object under assigns.auth0_claims. It also attaches the bearer token under assigns.auth0_access_token.

2. GetUser

This plug takes one option user_from_claim which is where you define how you want to use the information from the claim to fetch or create a user. There exists many ways to handle this so we leave it up to you.

Example Router & Controller

# router.ex
defmodule YourAppWeb.Router do
  use YourAppWeb, :router

  pipeline :api do
    plug :accepts, ["json"]
    plug Auth0Jwks.Plug.ValidateToken
    plug Auth0Jwks.Plug.GetUser, user_from_claim: &YourApp.Accounts.user_from_claim/2
  end

  scope "/api", YourAppWeb do
    pipe_through :api
    post "/validate_token", AuthController, :validate
  end
end

# accounts.ex
defmodule YourApp.Accounts do
  def user_from_claim(claims, token) do
    # Here you should take the `sub` value from `claims` and use it to fetch a user from your database.
    # If you don't find a user then create one.
    case get_user_by_sub(claims["sub"]) do
      nil ->
        # Note: we've provided a helper method to get more information from Auth0 about your user.
        # However call it sparingly as the endpoint is rate limited.
        {:ok, auth0_user_info} = Auth0Jwks.UserInfo.from_token(token)
        create_user_from_auth0(auth0_user_info)

      existing_user ->
        existing_user
    end
  end

  def get_user_by_sub(sub) do
    # query your database or something
  end

  def create_user_from_auth0(auth0_user_info) do
    # insert into your database or something
  end

end

4. Fetching your user

defmodule YourApp.AuthController do
  use YourAppWeb, :controller
  import Plug.Conn

  def validate(%{assigns: %{current_user: current_user}} = conn, _body) do
    IO.inspect(current_user, label: "Your current user")

    conn
    |> put_status(:accepted)
    |> json("User found with email #{current_user["email"]}")
  end
end

Additional Configuration

1. Set your json parse library

In your config you can specify an alternative JSON parsing librar

# config.exs
config :auth0_jwks, iss: System.get_env("AUTH0_DOMAIN"),
                    aud: System.get_env("AUTH0_AUDIENCE"),
                    json_library: Jason

1. No not halt on missing Token or User

You can tell each plug not to halt if theres no token or user

# router.ex
pipeline :api do
  plug :accepts, ["json"]
  plug Auth0Jwks.Plug.ValidateToken, no_halt: true
  plug Auth0Jwks.Plug.GetUser, no_halt: true, user_from_claim: &YourApp.Accounts.user_from_claim/2
end

About

πŸ”Œ An Auth0 plug for Elixir meant to help you decode and user Auth0 JWKs

License:Other


Languages

Language:Elixir 100.0%