danww

danww

Hi there,

I have an Elm frontend app, performing user login and token creation with Auth0 Lock, and then performing requests to a Phoenix API on the backend, passing the JWT token from Elm to Phoenix in an “Authorization: Bearer ” header.

I want the Phoenix API to be able to verify the supplied token in order to auth the request from the client app.

I’m currently using Guardian(API Reference — Guardian v2.4.0), configured along these lines:
Can I verify a JWToken created by Auth0 ? · Issue #211 · ueberauth/guardian · GitHub

I’m new to Phoenix.
I can’t get past ‘plug Guardian.Plug.EnsureAuthenticated’.
I’m not sure how to debug/inspect router/pipeline.
Ideally, I’d like Guardian.Plug.EnsureAuthenticated to reside in the pipeline, rather than in each controller.

Am I correct in assuming that Guardian will actually verify the supplied token with Auth0?
Because there doesn’t seem to be any provision in the config for the Auth0 ‘client_id’, which I expect would be necessary.

Showing Posts 1 to 10

krapans

krapans

How do you pass in the request from front-end the JWT token?

danww

danww OP

I’m adding a header (Authorization: Bearer <token>) to the request.
I understand Guardian should find and verify this token with the plug Guardian.Plug.VerifyHeader, realm: "Bearer" in the pipeline. I’m using the same Auth0 secret in the config for both client and server.

krapans

krapans

Ok, from this what you are saying everything sounds fine. I guess you need provide some code examples, so maybe then I could check out it and give you feedback.

danww

danww OP

Okay - here’s my code. Let me know if I’ve missed anything out.

config.exs

# Configures Guardian
config :guardian, Guardian,
  allowed_algos: ["HS256"],
  verify_module: Guardian.JWT,
  issuer: <Auth0 domain, same as is used client-side>,
  verify_issuer: true,
  secret_key: <Auth0 client secret, same as is used client-side for token generation>,
  serializer: MyApp.GuardianSerializer

###router.ex

  # pipeline for api
  pipeline :api do
    plug :accepts, ["json"]
    plug Guardian.Plug.VerifyHeader, realm: "Bearer "
    plug Guardian.Plug.EnsureAuthenticated
    plug Guardian.Plug.LoadResource
  end

Serializer

defmodule MyApp.GuardianSerializer do
  @behaviour Guardian.Serializer
  def for_token(id), do: {:ok, id}
  def from_token(id), do: {:ok, id}
end
krapans

krapans

For me, this looks like this plug Guardian.Plug.VerifyHeader, realm: "Bearer"

And Serializer like this

defmodule MyApp.GuardianSerializer do
  @behaviour Guardian.Serializer

  alias MyApp.Repo
  alias MyApp.User

  def for_token(account = %User{}), do: { :ok, "Account:#{account.id}" }
  def for_token(_), do: { :error, "Unknown resource type" }

  def from_token("Account:" <> id), do: { :ok, Repo.get(User, id) }
  def from_token(_), do: { :error, "Unknown resource type" }
end
danww

danww OP

I currently don’t have Ecto or a Repo set up - not sure I’ll need one, since this API is going to talk straight to another third-party API, so the Serializer isn’t really required, in my case.

I’m still not getting past the VerifyHeader plug - EnsureAuthenticated is failing.
I’m thinking my issue is around the Guardian config. I’m wondering if I’m missing something.

bryanjos

bryanjos

Was on a project recently with auth0 and guardian and got it to work. I think maybe try setting verify_issuer to false

danww

danww OP

I started from the beginning, setting up Guardian from scratch, and it worked.
I’m still not clear why it wasn’t working in the first instance.

If anyone is interested, I did the following:

mix.exs:

  • Added Guardian.
...
def application do
  [mod: {MyApp, []},
   applications: [:phoenix, ..., :guardian, ...]]
end

...

defp deps do
  [{:phoenix, "~> 1.2.1"},
   ...,
   {:guardian, "~> 0.14"}]
end

…then ran mix deps.get

config.exs

  • set allowed_algos to HS256
  • set issuer to Auth0 domain
  • set verify_issuer to false. This may have been what solved it, although I did try changing this in my initial attempt.
  • set secret_key to Auth0 client secret
  • set up my own serializer - see next step.
...
config :guardian, Guardian,
  allowed_algos: ["HS256"], # optional
  verify_module: Guardian.JWT,  # optional
  issuer: <Auth0 domain>,
  ttl: { 30, :days },
  allowed_drift: 2000,
  verify_issuer: false,
  secret_key: <Auth0 client secret>,
  serializer: MyApp.GuardianSerializer

...

serializer.ex

  • I’m not getting anything in/out of the token at this point, so this is not of any significance, just yet
defmodule MyApp.GuardianSerializer do
  @behaviour Guardian.Serializer

  def for_token(id), do: {:ok, id}
  def from_token(id), do: {:ok, id}

end

router.ex

  • Added the following Guardian plugs to the exisiting :api pipeline, as follows
...
pipeline :api do
  plug :accepts, ["json"]
  plug Guardian.Plug.VerifyHeader, realm: "Bearer"
  plug Guardian.Plug.EnsureAuthenticated
  plug Guardian.Plug.LoadResource
end
...

And that seemed to do the trick.

Thanks all, for your help

mihaimartalogu

mihaimartalogu

Late to the party, but I use the same scenario, and I just managed to make it work after a bit of pain.

I had to:

  1. Set allowed_algos to [“RS256”]
    Authorization API signs JWTs as RS256 when HS256 is selected - Auth0 Community
  2. Set the issuer to exactly what the JWT says (i.e. including the leading “https://” and the trailing “/”). Check the “iss” field of your token on https://jwt.io/
  3. Use the public key (found under Auth0 → → Settings → Advanced Settings → Certificates → Signing Certificate), passed through JOSE.JWK.from_pem/1 as Guardian’s secret_key

Note that, as mentioned in %FunctionClauseError{arity: 1, function: :jose_jwk, module: Guardian} · Issue #291 · ueberauth/guardian · GitHub, you can’t call JOSE.JWK.from_pem/1 from config.exs, so I had to move that call into the application start/2 function:

# (in config.exs)
...
config :guardian, Guardian,
  ...
  secret_key_pem: "-----BEGIN CERTIFICATE-----..."
  ...

# (in <app>/lib/<app-name>.ex)
def start(_type, _args) do
  guardian_env = Application.get_env(:guardian, Guardian)
  secret_key = guardian_env |> Keyword.get(:secret_key_pem) |> JOSE.JWK.from_pem
  new_guardian_env = guardian_env |> Keyword.put(:secret_key, secret_key)
  Application.put_env(:guardian, Guardian, new_guardian_env)

Hope this helps

arcseldon

arcseldon

This blog details how the OP performed the same JWT Verification of Auth0 access token. Code also provided.

https://madebymany.com/stories/how-we-built-passwordless-authentication-with-auth0-and-elixir-phoenix

— All posts loaded —

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
peck
Hi everyone. My team and I have been working on a fairly modest app based around video streaming and chat, but we’ve landed a customer t...
New
achenet
Hello, I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind. However, when I launch mix phx.server, I get an error...
New
bradley
I really like the adapter patterns that ecto, nebulex, waffle, etc. use and would love find something similar for a key management servic...
New
unaware8150
Hello folks! So at work, we are seeing some situations where we have to define some “fixed” strings that are used across the codebase in...
New
Cxx-mlr
I’m working on a small exercise involving update_in/3, and I came up with this solution: data = %{ name: "Periodic Table", category:...
New
Alvinkariuki
How Can I Optimise Compile Time Dependencies I have been building an elixir application for about 2 years now. Many modules and files ha...
New

Other Trending Topics Top

budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
juhalehtonen
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New
budgie
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with. But I don’t use it anymore. Serverless was the promis...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews