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)
  if !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.each do |key, value|
    values << "#{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 - ActionController::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 header = request.authorization.to_s[/^Token (.*)/]
    values = $1.split(',').
      inject({}) do |memo, 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
        memo.update(key => value)
      end
    [values.delete("token"), values.with_indifferent_access]
  end
end