View Source Goth.Token (Goth v1.3.0-rc.4)

Functions for retrieving the token from the Google API.

Link to this section Summary

Functions

Fetch the token from the Google API using the given config.

Link to this section Types

@type t() :: %Goth.Token{
  account: term(),
  expires: non_neg_integer(),
  scope: String.t(),
  sub: String.t() | nil,
  token: String.t(),
  type: String.t()
}

Link to this section Functions

Link to this function

fetch(config)

View Source (since 1.3.0)
@spec fetch(map()) :: {:ok, t()} | {:error, Exception.t()}

Fetch the token from the Google API using the given config.

Config may contain the following keys:

  • :source - See "Source" section below.

  • :http_client - a funtion that makes the HTTP request.

    Can be one of the following:

    • fun - same as {fun, []}

    • {fun, opts} - fun must be a 1-arity funtion that receives a keyword list with fields :method, :url, :headers, and :body along with any passed opts. The funtion must return {:ok, %{status: status, headers: headers, body: body}} or {:error, exception}. See "Custom HTTP Client" section below for more information.

    fun can also be an atom :hackney to use the built-in Hackney-based client.

    Defaults to {:hackney, []}.

source

Source

Source can be one of:

Service account - {:service_account, credentials, options}

The credentials is a map and can contain the following keys:

  • "private_key"

  • "client_email"

The options is a keywords list and can contain the following keys:

  • :url - the URL of the authentication service, defaults to: "https://www.googleapis.com/oauth2/v4/token"

  • :scopes - the list of token scopes, defaults to ["https://www.googleapis.com/auth/cloud-platform"] (ignored if :claims present)

  • :claims - self-signed JWT extra claims. Should be a map with string keys only. A self-signed JWT will be exchanged for a Google-signed ID token

Refresh token - {:refresh_token, credentials, options}

The credentials is a map and can contain the following keys:

  • "refresh_token"

  • "client_id"

  • "client_secret"

The options is a keywords list and can contain the following keys:

  • :url - the URL of the authentication service, defaults to: "https://www.googleapis.com/oauth2/v4/token"

Google metadata server - {:metadata, options}

The options is a keywords list and can contain the following keys:

  • :account - the name of the account to generate the token for, defaults to "default"

  • :url - the URL of the metadata server, defaults to "http://metadata.google.internal"

  • :audience - the audience you want an identity token for, default to nil If this parameter is provided, an identity token is returned instead of an access token

custom-http-client

Custom HTTP Client

To use a custom HTTP client, define a function that receives a keyword list with fields :method, :url, :headers, and :body. The funtion must return {:ok, %{status: status, headers: headers, body: body}} or {:error, exception}.

Here's an example with Hackney:

defmodule MyApp do
  def request_with_hackney(options) do
    {method, options} = Keyword.pop!(options, :method)
    {url, options} = Keyword.pop!(options, :url)
    {headers, options} = Keyword.pop!(options, :headers)
    {body, options} = Keyword.pop!(options, :body)
    options = [:with_body] ++ options

    case :hackney.request(method, url, headers, body, options) do
      {:ok, status, headers, response_body} ->
        {:ok, %{status: status, headers: headers, body: response_body}}

      {:error, reason} ->
        {:error, RuntimeError.exception(inspect(reason))}
    end
  end
end

And here is how it can be used:

iex> Goth.Token.fetch(%{source: source, http_client: &MyApp.request_with_hackney/1})
{:ok, %Goth.Token{...}}

iex> Goth.Token.fetch(%{source: source, http_client: {&MyApp.request_with_hackney/1, connect_timeout: 5000}})
{:ok, %Goth.Token{...}}

examples

Examples

Generate a token using a service account credentials file:

iex> credentials = "credentials.json" |> File.read!() |> Jason.decode!()
iex> Goth.Token.fetch(%{source: {:service_account, credentials, []}})
{:ok, %Goth.Token{...}}

You can generate a credentials file containing service account using gcloud utility like this:

$ gcloud iam service-accounts keys create --key-file-type=json --iam-account=... credentials.json

Generate a cloud function invocation token using a service account credentials file:

iex> credentials = "credentials.json" |> File.read!() |> Jason.decode!()
...> claims = %{"target_audience" => "https://<GCP_REGION>-<PROJECT_ID>.cloudfunctions.net/<CLOUD_FUNCTION_NAME>"}
...> Goth.Token.fetch(%{source: {:service_account, credentials, [claims: claims]}})
{:ok, %Goth.Token{...}}

Generate an impersonated token using a service account credentials file:

iex> credentials = "credentials.json" |> File.read!() |> Jason.decode!()
...> claims = %{"sub" => "<IMPERSONATED_ACCOUNT_EMAIL>"}
...> Goth.Token.fetch(%{source: {:service_account, credentials, [claims: claims]}})
{:ok, %Goth.Token{...}}

Retrieve the token using a refresh token:

iex> credentials = "credentials.json" |> File.read!() |> Jason.decode!()
iex> Goth.Token.fetch(%{source: {:refresh_token, credentials, []}})
{:ok, %Goth.Token{...}}

You can generate a credentials file containing refresh token using gcloud utility like this:

$ gcloud auth application-default login

Retrieve the token using the Google metadata server:

iex> Goth.Token.fetch(%{source: {:metadata, []}})
{:ok, %Goth.Token{...}}

See Storing and retrieving instance metadata for more information on metadata server.

Passing custom Hackney options

iex> Goth.Token.fetch(%{source: source, http_client: {:hackney, connect_timeout: 5000}})
{:ok, %Goth.Token{...}}
Link to this function

for_scope(info, sub \\ nil)

View Source
This function is deprecated. Use Goth.fetch/1 instead.
@spec for_scope(scope :: String.t(), sub :: String.t() | nil) ::
  {:ok, t()} | {:error, any()}
@spec for_scope(info :: {String.t() | atom(), String.t()}, sub :: String.t() | nil) ::
  {:ok, t()} | {:error, any()}