module Picnic::Authentication::Basic
Picnic::Authentication::Basic provides Basic HTTP Authentication for your Camping app. The
module defines a service
method that only continues the
request chain when proper credentials are provided by the client
(browser).
Getting Started¶ ↑
To activate Basic Authentication for your application:
-
Picnic-fy your Camping app (e.g:
Camping.goes :your_app; YourApp.picnic!
) -
Call
YourApp.authenticate_using :basic
. -
Define an
authenticate
method on your application module that takes a hash. The hash contains credentials like:username
,:password
, and:hostname
, although future authentication modules may submit other credentials. Theauthenticate
method should return true when the credentials are valid. Examples:module Blog def authenticate(credentials) credentials[:username] == 'admin' && credentials[:password] == 'flapper30' end module_function :authenticate end
or
module Wiki def authenticate(credentials) u = credentials[:username] p = credentials[:password] Models::User.find_by_username_and_password u, p end module_function :authenticate end
-
service
sets@credentials
to the credentials of the person who logged in.
This code is based on Camping::BasicAuth written by Manfred Stienstra (see www.fngtps.com/2006/05/basic-authentication-for-camping).
Public Instance Methods
Reads the username and password from the headers and returns them.
# File lib/picnic/authentication.rb, line 87 def read_credentials if d = %w{REDIRECT_X_HTTP_AUTHORIZATION X-HTTP_AUTHORIZATION HTTP_AUTHORIZATION}.inject([]) { |d,h| @env.has_key?(h) ? @env[h].to_s.split : d } u,p = ::Base64.decode64(d[1]).split(':')[0..1] if d[0] == 'Basic' return {:username => u, :password => p} end end
# File lib/picnic/authentication.rb, line 95 def service(*a) app = Kernel.const_get self.class.name.gsub(/^(\w+)::.+$/, '\1') unless app.respond_to? :authenticate raise "Basic authentication is enabled but the 'authenticate' method has not been defined." end @credentials = read_credentials || {} if app.authenticate(@credentials) s = super(*a) else @status = 401 headers['Content-type'] = @headers['Content-type'] || 'text/plain' #headers['Status'] = 'Unauthorized' headers['WWW-Authenticate'] = "Basic realm=\"#{app}\"" @body = 'Unauthorized' s = self end s end