Skip to content

Instantly share code, notes, and snippets.

@caherrerapa
Forked from kapkaev/faraday_digest_auth.rb
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save caherrerapa/bd912214700e556182d1 to your computer and use it in GitHub Desktop.
Save caherrerapa/bd912214700e556182d1 to your computer and use it in GitHub Desktop.
require 'faraday'
require 'net/http/digest_auth'
module Faraday
# Public: A Faraday middleware to use digest authentication. Since order of
# middlewares do care, it should be the first one of the Request middlewares
# in order to work properly (due to how digest authentication works).
#
# If some requests using the connection don't need to use digest auth you
# don't have to worry, the middleware will do nothing.
#
# It uses Net::HTTP::DigestAuth to generate the authorization header but it
# should work with any adapter.
#
# Examples:
#
# connection = Faraday.new(...) do |connection|
# connection.request :digest, USER, PASSWORD
# end
#
# # You can also use it later with a connection:
# connection.digest_auth('USER', 'PASSWORD')
#
class Request::DigestAuth < Faraday::Middleware
# Public: Initializes a DigestAuth.
#
# app - The Faraday app.
# user - A String with the user to authentication the connection.
# password - A String with the password to authentication the connection.
def initialize(app, user, password)
super(app)
@user, @password = user, password
end
# Public: Sends a first request with an empty body to get the
# authentication headers and then send the same request with the body and
# authorization header.
#
# env - A Hash with the request environment.
#
# Returns a Faraday::Response.
def call(env)
response = handshake(env)
return response unless response.status == 401
env[:request_headers]['Authorization'] = header(response)
@app.call(env)
end
private
# Internal: Sends the the request with an empry body.
#
# env - A Hash with the request environment.
#
# Returns a Faraday::Response.
def handshake(env)
env_without_body = env.dup
env_without_body.delete(:body)
@app.call(env_without_body)
end
# Internal: Builds the authorization header with the authentication data.
#
# response - A Faraday::Response with the authenticate headers.
#
# Returns a String with the DigestAuth header.
def header(response)
uri = response.env[:url]
uri.user = @user
uri.password = @password
realm = response.headers['www-authenticate']
method = response.env[:method].to_s.upcase
Net::HTTP::DigestAuth.new.auth_header(uri, realm, method)
end
end
class Connection
# Public: Adds the digest auth middleware at the top and sets the user and
# password.
#
# user - A String with the user.
# password - A String with the password.
#
def digest_auth(user, password)
self.builder.insert(0, Faraday::Request::DigestAuth, user, password)
end
end
end
# Register the middleware as a Request middleware with the name :digest
Faraday::Request.register_middleware digest: Faraday::Request::DigestAuth
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment