Sinatra Basic Authentication - Selectively Applied
Most web applications have some sort of admin area where users shouldn’t be. Passwording it is the obvious solution, but it isn’t obvious how to implement passwords in Sinatra. I stole this code from Ryan Tomayko’s Wink blog, and extracted it into a more generic module for reuse. Two parts are involved, the module, which I put into a separate file, and include. And then the code itself to pull it into the helpers and use it in the event handlers.
The module:
module Sinatra
module Authorization
def auth
@auth ||= Rack::Auth::Basic::Request.new(request.env)
end
def unauthorized!(realm="myApp.com")
header 'WWW-Authenticate' => %(Basic realm="#{realm}")
throw :halt, [ 401, 'Authorization Required' ]
end
def bad_request!
throw :halt, [ 400, 'Bad Request' ]
end
def authorized?
request.env['REMOTE_USER']
end
def authorize(username, password)
# Insert your logic here to determine if username/password is good
false
end
def require_administrative_privileges
return if authorized?
unauthorized! unless auth.provided?
bad_request! unless auth.basic?
unauthorized! unless authorize(*auth.credentials)
request.env['REMOTE_USER'] = auth.username
end
def admin?
authorized?
end
end
end
To use the module:
require 'authorization'
helpers do
include Sinatra::Authorization
end
get '/admin' do
require_administrative_privileges
# Do private stuff
end
EDIT: Thanks to foca on #sinatra for the nicer setup of authorize
License: Because this was extracted out of Wink, follow the Wink license (found here).
July 17th, 2008 at 9:47 pm
I’d extract the credentials array into a separate method in the module. That way it can be overridden in the helpers block to allow people to include the module without the need to modify it :)
July 18th, 2008 at 12:24 am
Oh yeah! Rack is full of gems, it seems.
August 4th, 2008 at 7:43 pm
I’m a bit confused, how can those elements not be in a string?
Also, the first line of unauthorized! is giving me problems.
August 4th, 2008 at 7:44 pm
woops.. accidentally put an open span element in the last comment.
ment to say “span elements”
August 4th, 2008 at 7:55 pm
tolas: that’s wordpress being very dumb. Sorry about that.
August 7th, 2008 at 5:13 pm
hi
This doesn’t work for me
$ ruby privatestuff.rb
privatestuff.rb:1:in `require’: ./authorization.rb:9: syntax error, unexpected ‘;’ (SyntaxError)
header ‘WWW-Authenticate’ =>; %(Basic realm=”#{realm}”)
^ from privatestuff.rb:1
//
on ubuntu 8.04, ruby 1.8.6 (2007-09-24 patchlevel 111) [i486-linux]
August 7th, 2008 at 5:18 pm
ben, I am going to have to put this up on a pastie or something, since wordpress keeps messing with the formatting of certain entities mainly > and &. Just remove the semi colon and move on.
October 25th, 2008 at 8:14 pm
Hi,
How can I logout user using HTTP authentication?