Class: X::Authenticator

Inherits:
Object
  • Object
show all
Includes:
CredentialHolder
Defined in:
x-core/lib/x/core/authenticator.rb

Overview

Base class for authentication

Subclass it to authenticate with a scheme of your own, overriding #headers, as the authenticators of x-core do.

Constant Summary collapse

AUTHENTICATION_HEADER =

The HTTP header name for authentication

"Authorization"

Instance Method Summary collapse

Instance Method Details

#headers(_request) ⇒ Hash{String => String}

Generate the authentication headers for a request, which authenticates as no one

A client calls it for every request it sends to the origin of its base URL, and every stream it opens there, once the request is built, just before it is sent, and sends each header it returns, in place of any header of the same name. Its method, URI, headers, and body are set, so an authenticator of your own can sign any of them: subclass X::Authenticator and override this method, and give an instance to the authenticator: of X::Client.new or X::Client#with. A request to another origin, such as one a redirect leads to, is not passed to it, so its headers never leave the origin they were built for. It is called on the thread that sends the request, so one a client shares across threads must be thread-safe.

The request answers four methods alone, which are all the authenticators of x-core read of it: http_method, the HTTP method as a Symbol, such as :post, as a response and an error name it; uri, the URI::Generic it is sent to, query included; body, the String it sends, or nil for none; and [], the value of a header by its name, in any case, or nil for one it does not send. It answers them alone whatever request the client sends, so an authenticator of your own reads nothing a later version of 1.x could take away.

A client refreshes the token of none but its own OAuth 2.0 authenticator, so an authenticator of your own that holds a token that expires refreshes it here. A client given one takes it to authenticate as the app, as it does an X::Authenticator itself, so app_only returns the client, and a stream is opened with it.

Examples:

Authenticate every request with a token an application keeps

class VaultAuthenticator < X::Authenticator
  def headers(_request) = {AUTHENTICATION_HEADER => "Bearer #{Vault.read("x/bearer_token")}"}
end
client = X::Client.new(authenticator: VaultAuthenticator.new)

Parameters:

  • _request (#http_method, #uri, #body, #[]) —

    the request, which answers http_method, uri, body, and [] alone

Returns:

  • (Hash{String => String}) —

    the headers that authenticate the request, empty for none



47
48
49
# File 'x-core/lib/x/core/authenticator.rb', line 47

def headers(_request)
  {}
end

#inspect ⇒ String

Summarize the authenticator for the console without revealing credentials

Examples:

Inspect an authenticator

authenticator.inspect # => #<X::BearerTokenAuthenticator>

Returns:

  • (String) —

    the class name



69
70
71
# File 'x-core/lib/x/core/authenticator.rb', line 69

def inspect
  "#<#{self.class}>"
end

#user_id ⇒ Integer?

The identifier of the user the credentials act for, when they name one

Only an OAuth 1.0a access token names its user, so every other set of credentials answers nil, and the caller that wants the user of such a client asks the API for it.

Examples:

Read the user a client acts for without a request

client.authenticator.user_id # => nil

Returns:

  • (Integer, nil) —

    the identifier, or nil for credentials that name no user



60
61
# File 'x-core/lib/x/core/authenticator.rb', line 60

def user_id
end