Hi all,
I’m writting a small app that requires basic authentication in Sinatra.
I followed the advice of the official Sinatra faq
(Sinatra: Frequently Asked Questions) and have implemented this code
with success:
require 'rubygems'
require 'sinatra'
helpers do
def protected!
response['WWW-Authenticate'] = %(Basic realm="Testing HTTP Auth")
and \
throw(:halt, [401, "Not authorized\n"]) and \
return unless authorized?
end
def authorized?
@auth ||= Rack::Auth::Basic::Request.new(request.env)
@auth.provided? && @auth.basic? && @auth.credentials &&
@auth.credentials == ['admin', 'admin']
end
end
get '/' do
"Everybody can see this page"
end
get '/protected' do
protected!
"Welcome, authenticated client"
end
So I get a window asking me to ender my credentials when going to
/protected and it logs me in. Once logged in though, I would like to be
able to log out. I know the solution to this must be super easy but I
just can’t get it to work.
Any help is greatly appreciated. Thanks!
-Tony
Just realized I posted this to the rails forum instead of the ruby
forum. Sorry!
Ahh… there go my hopes for a simple and secure login/logout system!
Many thanks for the useful information before I started ripping my hair
out!
Any suggestions on another easy to implement login/logout system? I
don’t require user signups. I just want to hardcode maybe 2 or 3
usernames and passwords that I could enter from a ‘/login’ page. This is
only for my personal use.
Thanks again!
-Tony
Go with the simplest solution - have a ‘login’ action that checks
against the hard-coded info, then sets a cookie. Check for that in
your protected actions (something like the code in protected! you
posted), and clear the cookie on logout.
(No idea what cookie handling looks like on Sinatra, but it should be
easy)
–Matt J.
Thanks for the reply Matt!
I did something like this… I’d like to know what you and others think
of it as far as security goes. While it’s not a bank or anything, I’d
like my app to be as hacker proof as possible. Any suggestions to make
it more secure are welcome!
Many thanks guys!
–
LOGIN FORM (GET LOGIN METHOD)
Username
Password
Login
POST LOGIN METHOD
post ‘/login’ do
if authenticate(params[“post”][“username”],
Digest::MD5.hexdigest(params[“post”][“password”]))
session[:user] = params[“post”][“username”]
flash[:notice] = “Login succeeded!”
redirect ‘/admin’
else
flash[:error] = “Login failed!”
redirect ‘/login’
end
end
HELPER METHODS
Authentication is hard-coded as there will only 1-3 users
def authenticate(username, password)
if username == 'admin' and password == '[admin_password_in_MD5]'
return true
else
return false
end
end
Protect pages
def login_required
if session[:user]
return true
else
redirect ‘/login’
return false
end
end
Get the username of the logged in user
def current_user
if session[:user]
session[:user]
end
end
Verify if a user is logged in
def logged_in?
!!session[:user]
end
–
Anyway, I hope this helps others looking for a simple login method.
Best regards,
Tony
Basic authentication doesn’t support the concept of “logging out” -
see this Apache FAQ:
http://httpd.apache.org/docs/1.3/howto/auth.html#basicfaq
–Matt J.