module ActionController::HttpAuthentication::Token

def authenticate(controller, &login_procedure)

Returns nil if no token is found.
Returns the return value of `&login_procedure` if a token is found.

authenticate(controller) { |token, options| ... }
take 2 arguments:
login_procedure - Proc to call if a token is present. The Proc should
controller - ActionController::Base instance for the current request.

the present token and options.
If token Authorization header is present, call the login procedure with
def authenticate(controller, &login_procedure)
  token, options = token_and_options(controller.request)
  unless token.blank?
    login_procedure.call(token, options)
  end
end

def authentication_request(controller, realm)

Returns nothing.

realm - String realm to use in the header.
controller - ActionController::Base instance for the outgoing response.

Sets a WWW-Authenticate to let the client know a token is desired.
def authentication_request(controller, realm)
  controller.headers["WWW-Authenticate"] = %(Token realm="#{realm.gsub(/"/, "")}")
  controller.__send__ :render, :text => "HTTP Token: Access denied.\n", :status => :unauthorized
end

def encode_credentials(token, options = {})

Returns String.

options - optional Hash of the options.
token - String token.

Encodes the given token and options into an Authorization header value.
def encode_credentials(token, options = {})
  values = ["token=#{token.to_s.inspect}"] + options.map do |key, value|
    "#{key}=#{value.to_s.inspect}"
  end
  "Token #{values * ", "}"
end

def token_and_options(request)

Returns nil if no token is found.
Returns an Array of [String, Hash] if a token is present.

request - ActionDispatch::Request instance with the current headers.

Then the returned token is "abc", and the options is {:nonce => "def"}
Authorization: Token token="abc", nonce="def"
the header looks like this:
Parses the token and options out of the token authorization header. If
def token_and_options(request)
  if request.authorization.to_s[/^Token (.*)/]
    values = Hash[$1.split(',').map do |value|
      value.strip!                      # remove any spaces between commas and values
      key, value = value.split(/\=\"?/) # split key=value pairs
      value.chomp!('"')                 # chomp trailing " in value
      value.gsub!(/\\\"/, '"')          # unescape remaining quotes
      [key, value]
    end]
    [values.delete("token"), values.with_indifferent_access]
  end
end