我已经设置了Firebase进行前端身份验证,并将ID令牌(即JWT)发送到我的凤凰后端。
我现在正试图验证JWT。
关于此事的Google说明为here。 tldr,获取可公开访问的证书,并使用它来验证JWT签名是否已使用正确的私钥签名。
我到目前为止有这个
ggplot
我迷路了。我需要将公共证书转换为公共密钥吗?如何使用RS256签名算法和公共证书创建Joken.Signer?我愿意不使用Joken的解决方案。
谢谢!
答案 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