adao

adao

Verifying Firebase ID Token with Joken

I’ve set up Firebase for frontend authentication and I am sending the ID token, which is a JWT, to my phoenix backend.

I am now stuck trying to verify the JWT.

Google instructions regarding the matter are here. TLDR: Grab the public accessible certificate and use it to verify the JWT signature was signed with the correct private key.

I have this so far

def verify(token) do
  {:ok, resp} = HTTPoison.get(@cert_url)
  %{body: body} = resp
  body = Poison.Parser.parse!(body, %{})
  {:ok, header} = Joken.peek_header(token)
  cert = body[header["kid"]]
end

I’m lost there. Do I need to convert the public certificate to a public key? How do I create a Joken.Signer with RS256 signing algorithm and the public certificate?

Thank you!

Most Liked

1guzzy

1guzzy

Thanks for the code. I cleaned it up a bit for the next guy.

def verify(token) do
    with {:ok, jwk} <- get_jwk(token),
         {true, jose_jwt, _} = JOSE.JWT.verify(jwk, token),
         {_, claims} <- JOSE.JWT.to_map(jose_jwt) do
      {:ok, claims}
    end
  end

  def get_jwk(token) do
    with {:ok, %{body: body}} <- HTTPoison.get(@cert_url),
         {:ok, certs} <- Jason.decode(body),
         {:ok, header} <- Joken.peek_header(token) do
      jwk =
        certs
        |> JOSE.JWK.from_firebase()
        |> Map.get(header["kid"])
        |> JOSE.JWK.to_map()
        |> elem(1)

      {:ok, jwk}
    end
  end
adao

adao

I found the JOSE library :grin:

To finish up the code…

def verify(token) do
  {:ok, resp} = HTTPoison.get(@cert_url)
  %{body: body} = resp
  certs = Poison.Parser.parse!(body, %{})
  {:ok, header} = Joken.peek_header(token)
  jwks = JOSE.JWK.from_firebase(certs)
  jwk = jwks[header["kid"]] |> JOSE.JWK.to_map |> elem(1)
  {true, jose_jwt, _} = JOSE.JWT.verify(jwk, token)
  fields = JOSE.JWT.to_map(jose_jwt) |> elem(1)
  {:ok, fields}
end

Elixir code can probably be cleaned up :sweat_smile:

Where Next?

Popular in Questions Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New

Other popular topics Top

lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New

We're in Beta

About us Mission Statement