Kinde (kinde v2.1.0)

Copy Markdown View Source

OpenID Connect authentication with PKCE for Kinde.

Provides two main functions:

  • auth/2 — generates an OAuth2 authorization URL and stores the PKCE code verifier in state management
  • token/4 — exchanges the authorization code for an ID token, verifies it, and returns user attributes

Configuration

Required keys can be set via application config or passed directly as a map:

config :kinde,
  domain: "https://yourapp.kinde.com",
  client_id: "client_id",
  client_secret: "client_secret",
  redirect_uri: "http://localhost:4000/callback"

When a map is passed to auth/2 or token/4, its values take precedence over the application config. See the "All configuration keys" section in the README for a complete reference.

Example

# Step 1: redirect user to Kinde
{:ok, url} = Kinde.auth()

# Step 2: handle the callback
{:ok, token_response, extra_params} = Kinde.token(code, state)

Summary

Functions

Generates an OAuth2 authorization URL with PKCE.

Exchanges an authorization code for user attributes.

Types

config()

@type config() :: %{
  optional(:domain) => String.t(),
  optional(:client_id) => String.t(),
  optional(:client_secret) => String.t(),
  optional(:redirect_uri) => String.t(),
  optional(:prompt) => String.t(),
  optional(:scopes) => [String.t()]
}

state_params()

@type state_params() :: %{code_verifier: String.t(), extra_params: map()}

token_response()

@type token_response() :: %{
  access_token: String.t(),
  access_token_claims: map(),
  id_token: String.t(),
  id_token_claims: map(),
  refresh_token: String.t(),
  expires_in: non_neg_integer(),
  scope: String.t(),
  token_type: String.t()
}

Functions

auth(config \\ %{}, extra_params \\ %{})

@spec auth(config(), map()) :: {:ok, String.t()} | {:error, term()}

Generates an OAuth2 authorization URL with PKCE.

Accepts an optional config map (overrides app env) and an optional extra_params map that will be returned alongside user data after a successful token/4 call.

Returns {:ok, url} on success or {:error, %MissingConfigError{}} when required configuration keys are missing.

Examples

iex> Kinde.auth()
{:ok, "https://yourapp.kinde.com/oauth2/auth?..."}

iex> Kinde.auth(%{}, %{return_to: "/dashboard"})
{:ok, "https://yourapp.kinde.com/oauth2/auth?..."}

token(code, state, config \\ %{}, opts \\ [])

@spec token(String.t(), String.t(), config(), Keyword.t()) ::
  {:ok, token_response(), map()} | {:error, term()}

Exchanges an authorization code for user attributes.

Takes the code and state from the Kinde callback, verifies the ID token via JWKS, and returns user attributes along with any extra_params that were passed to auth/2.

Returns {:ok, token_response, extra_params} on success, where token_response is a token_response/0 map containing the full OAuth2 token endpoint response including decoded JWT claims.

Errors

  • {:error, %ObtainingTokenError{}} — the token endpoint returned an error
  • {:error, %StateNotFoundError{}} — the state was not found (expired or already used)
  • {:error, %MissingConfigError{}} — required config keys are missing