Currently, assent has support for Google Sign in for the web, the client sends the code and scope and the strategy retrieves from google the JWT with the data.
This works fine for the web, but not so much for mobile apps where normally the client will retrieve the JWT (id token) directly and the server job is to validate it.
Since I need exactly this case, I created a new strategy for it, you can add it to Assent if you want, and also I would appreciate it if you can take a look and see if there is some flaw in the logic.
The strategy itself is very simple, you simply send the id_token to id and it will validate it.
defmodule Core.Identity.GoogleSignIn.Strategy do
@moduledoc false
alias Core.Identity.GoogleSignIn.JWTManager
@behaviour Assent.Strategy
@impl true
def callback(_, params) do
%{id_token: id_token} = params
case JWTManager.verify_and_validate(id_token) do
{:ok, user} -> {:ok, %{user: user}}
{:error, _} -> {:error, :invalid_token}
end
end
@impl true
def authorize_url(_), do: throw("not implemented")
end
For validation, here are my modules:
defmodule Core.Identity.GoogleSignIn.JWTVerifyHook do
@moduledoc false
use Joken.Hooks
@impl true
def before_verify(_, {jwt, %Joken.Signer{}}) do
with {:ok, %{"kid" => kid}} <- Joken.peek_header(jwt),
{:ok, algorithm, key} <- GoogleCerts.fetch(kid) do
{:cont, {jwt, Joken.Signer.create(algorithm, key)}}
else
_ -> {:halt, {:error, :no_signer}}
end
end
end
defmodule Core.Identity.GoogleSignIn.JWTManager do
@moduledoc false
alias Core.Identity.GoogleSignIn.JWTVerifyHook
use Joken.Config, default_signer: nil
add_hook(JWTVerifyHook)
@iss "https://accounts.google.com"
@impl true
def token_config do
default_claims(skip: [:aud, :iss])
|> add_claim("iss", nil, fn iss -> iss == @iss end)
|> add_claim("aud", nil, fn aud -> aud == aud() end)
end
defp aud do
Application.fetch_env!(:core, :pow_assent)
|> Keyword.fetch!(:providers)
|> Keyword.fetch!(:google_sign_in)
|> Keyword.fetch!(:client_id)
end
end
Currently, assent has support for Google Sign in for the web, the client sends the code and scope and the strategy retrieves from google the JWT with the data.
This works fine for the web, but not so much for mobile apps where normally the client will retrieve the JWT (id token) directly and the server job is to validate it.
Since I need exactly this case, I created a new strategy for it, you can add it to Assent if you want, and also I would appreciate it if you can take a look and see if there is some flaw in the logic.
The strategy itself is very simple, you simply send the id_token to id and it will validate it.
For validation, here are my modules: