Class: StandardId::Providers::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/standard_id/providers/base.rb

Overview

Base class for social login providers.

All provider implementations (Google, Apple, GitHub, etc.) must inherit from this class and implement the required interface methods. This enables a plugin architecture where provider gems can be developed independently and registered with StandardId.

Examples:

Creating a custom provider

module StandardId
  module Providers
    class GitHub < Base
      def self.provider_name
        "github"
      end

      def self.authorization_url(state:, redirect_uri:, **options)
        # Build and return GitHub OAuth authorization URL
      end

      def self.(code: nil, id_token: nil, access_token: nil, redirect_uri: nil, **options)
        # Exchange credentials for user info and return standardized response
      end

      def self.config_schema
        {
          github_client_id: { type: :string, default: nil },
          github_client_secret: { type: :string, default: nil }
        }
      end
    end
  end
end

# Register the provider
StandardId::ProviderRegistry.register(:github, StandardId::Providers::GitHub)

Class Method Summary collapse

Class Method Details

.authorization_url(state:, redirect_uri:, **options) ⇒ String

Generate OAuth authorization URL for redirecting users to the provider.

Examples:

url = StandardId::Providers::Google.authorization_url(
  state: "encoded_state_data",
  redirect_uri: "https://app.example.com/auth/callback/google",
  scope: "openid email profile"
)

Parameters:

  • state (String)

    OAuth state parameter (typically encoded with redirect + session info)

  • redirect_uri (String)

    Callback URL where provider will redirect after authentication

  • options (Hash)

    Provider-specific options (scope, prompt, response_mode, etc.)

Returns:

  • (String)

    Full authorization URL to redirect user to

Raises:

  • (NotImplementedError)

    if not overridden by subclass



67
68
69
# File 'lib/standard_id/providers/base.rb', line 67

def authorization_url(state:, redirect_uri:, **options)
  raise NotImplementedError, "#{name} must implement .authorization_url"
end

.callback_pathString

Returns the callback path for this provider.

Used to build the OAuth redirect URI. Uses the engine’s route helpers to respect the mount path.

Examples:

Engine mounted at “/”

StandardId::Providers::Google.callback_path #=> "/auth/callback/google"

Engine mounted at “/identity”

StandardId::Providers::Google.callback_path #=> "/identity/auth/callback/google"

Returns:

  • (String)

    The callback path (respects engine mount path)



164
165
166
# File 'lib/standard_id/providers/base.rb', line 164

def callback_path
  StandardId::WebEngine.routes.url_helpers.auth_callback_provider_path(provider: provider_name)
end

.config_schemaHash

Define configuration schema fields for this provider.

Returns a hash of field definitions compatible with StandardConfig schema DSL. These fields will be registered under the :social configuration scope.

Examples:

def self.config_schema
  {
    github_client_id: { type: :string, default: nil },
    github_client_secret: { type: :string, default: nil }
  }
end

Returns:

  • (Hash)

    Field definitions with types and defaults



122
123
124
# File 'lib/standard_id/providers/base.rb', line 122

def config_schema
  {}
end

.default_scopeString?

Returns the default OAuth scope for this provider.

Can be overridden by passing :scope in authorization_url options. Returns nil by default, letting the provider use its own default.

Examples:

StandardId::Providers::Google.default_scope #=> "openid email profile"

Returns:

  • (String, nil)

    Default scope string



178
179
180
# File 'lib/standard_id/providers/base.rb', line 178

def default_scope
  nil
end

.get_user_info(code: nil, id_token: nil, access_token: nil, redirect_uri: nil, **options) ⇒ HashWithIndifferentAccess

Exchange OAuth credentials for user information.

Providers must support at least one of: authorization code, ID token, or access token. The method should validate the credentials with the provider and return standardized user information.

Examples:

Response format

{
  user_info: {
    "sub" => "unique_provider_user_id",
    "email" => "user@example.com",
    "email_verified" => true,
    "name" => "Full Name",
    # ... other provider-specific fields
  },
  tokens: {
    id_token: "...",
    access_token: "...",
    refresh_token: "..."
  }
}

Parameters:

  • code (String, nil) (defaults to: nil)

    OAuth authorization code (web flow)

  • id_token (String, nil) (defaults to: nil)

    JWT ID token (mobile/implicit flow)

  • access_token (String, nil) (defaults to: nil)

    Access token (implicit flow)

  • redirect_uri (String, nil) (defaults to: nil)

    Original redirect_uri for code exchange validation

  • options (Hash)

    Provider-specific options (client_id for Apple mobile, etc.)

Returns:

  • (HashWithIndifferentAccess)

    Standardized response with user_info and tokens

Raises:



103
104
105
# File 'lib/standard_id/providers/base.rb', line 103

def (code: nil, id_token: nil, access_token: nil, redirect_uri: nil, **options)
  raise NotImplementedError, "#{name} must implement .get_user_info"
end

.provider_nameString

Provider identifier used for routing and configuration.

Examples:

StandardId::Providers::Google.provider_name #=> "google"

Returns:

  • (String)

    Unique provider name (e.g., “google”, “apple”, “github”)

Raises:

  • (NotImplementedError)

    if not overridden by subclass



48
49
50
# File 'lib/standard_id/providers/base.rb', line 48

def provider_name
  raise NotImplementedError, "#{name} must implement .provider_name"
end

.resolve_params(params, context: {}) ⇒ Hash

Resolve provider-specific parameters based on context.

Override this method to customize parameters based on flow type, platform, or other contextual information. This allows providers to handle platform-specific requirements (e.g., Apple’s different client IDs for web vs mobile).

Examples:

Apple provider overriding for mobile flow

def self.resolve_params(params, context: {})
  if context[:flow] == :mobile
    params.merge(client_id: StandardId.config.apple_mobile_client_id)
  else
    params
  end
end

Parameters:

  • params (Hash)

    Base parameters from the controller

  • context (Hash) (defaults to: {})

    Contextual information

Options Hash (context:):

  • :flow (Symbol)

    The authentication flow (:web or :mobile)

Returns:

  • (Hash)

    Modified parameters with provider-specific adjustments



147
148
149
# File 'lib/standard_id/providers/base.rb', line 147

def resolve_params(params, context: {})
  params
end

.setupvoid

This method returns an undefined value.

Optional setup hook called when provider is registered.

Override this method to perform initialization tasks like:

  • Registering additional routes

  • Adding custom validations

  • Setting up caching for JWKS



237
238
239
# File 'lib/standard_id/providers/base.rb', line 237

def setup
  # Override in subclasses if needed
end

.skip_csrf?Boolean

Whether to skip CSRF verification for web callbacks.

Some providers (like Apple) use POST callbacks which require CSRF verification to be skipped. Override this method to return true if your provider uses POST callbacks.

Examples:

Apple provider (POST callback)

def self.skip_csrf?
  true
end

Returns:

  • (Boolean)

    true to skip CSRF verification



195
196
197
# File 'lib/standard_id/providers/base.rb', line 195

def skip_csrf?
  false
end

.supported_authorization_paramsArray<Symbol>

Returns list of supported authorization parameters for this provider.

Include :nonce in this list for OIDC providers to enable nonce validation. Nonce provides replay attack protection for ID tokens.

Examples:

def supported_authorization_params
  [:scope, :prompt, :nonce]
end

Returns:

  • (Array<Symbol>)

    List of supported parameters



224
225
226
# File 'lib/standard_id/providers/base.rb', line 224

def supported_authorization_params
  []
end

.supports_mobile_callback?Boolean

Whether this provider supports mobile callback flow.

Mobile callbacks are used when native apps (especially Android) need a server-side redirect back to the app after OAuth. For example, Apple Sign In on Android uses a web-based flow that requires the server to redirect back to the app.

Returns:

  • (Boolean)

    true if provider supports mobile callback



208
209
210
# File 'lib/standard_id/providers/base.rb', line 208

def supports_mobile_callback?
  false
end