在Elixir / Erlang中验证Firebase ID令牌

时间:2019-10-14 03:24:15

标签: firebase firebase-authentication erlang elixir phoenix-framework

我已经设置了Firebase进行前端身份验证,并将ID令牌(即JWT)发送到我的凤凰后端。

我现在正试图验证JWT。

关于此事的Google说明为here。 tldr,获取可公开访问的证书,并使用它来验证JWT签名是否已使用正确的私钥签名。

我到目前为止有这个

ggplot

我迷路了。我需要将公共证书转换为公共密钥吗?如何使用RS256签名算法和公共证书创建Joken.Signer?我愿意不使用Joken的解决方案。

谢谢!

2 个答案:

答案 0 :(得分:1)

我找到了JOSE库:D

完成代码...

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代码可能可以清理^ _ ^

答案 1 :(得分:1)

@fetching_water解决方案的惯用语版本略多一些,它使用更多的模式匹配并使用Hackney代替HTTPoison:

@cert_url "https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com"

def verify!(token) do
  {:ok, 200, _headers, ref} = :hackney.get(@cert_url)
  {:ok, body} = :hackney.body(ref)
  {:ok, %{"kid" => kid}} = Joken.peek_header(token)

  {true, %{fields: fields}, _} =
    body
    |> Jason.decode!()
    |> JOSE.JWK.from_firebase()
    |> Map.fetch!(kid)
    |> JOSE.JWT.verify(token)

  fields
end