首页 > 解决方案 > 在 Elixir/Erlang 中验证 Firebase ID 令牌

问题描述

我已经为前端身份验证设置了 Firebase,并且我正在将作为 JWT 的 ID 令牌发送到我的 phoenix 后端。

我现在一直在尝试验证 JWT。

谷歌关于此事的说明在这里。tldr,获取可公开访问的证书并使用它来验证 JWT 签名是否使用正确的私钥签名。

到目前为止我有这个

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

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

谢谢!

标签: firebasefirebase-authenticationerlangelixirphoenix-framework

解决方案


@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

推荐阅读