开发者

Sinatra: How do I provide access to a login form while preventing access to the rest of my Sinatra app?

I recently created a Sinatra app with a login form (no basic auth). To prevent access to the app unless the user logged in I put a before block in place

before do
  unless request.path_info == '/login'
    authenticated?
  end
end

I quickly realized that this prevented me from accessing resources in the public directory like my style sheet and logo unless authenticated first as well. To get around that I changed my filter to the following:

开发者_C百科before do
  unless request.path_info == '/login' || request.path_info == "/stylesheets/master.css" || request.path_info == "/images/logo.png"
    authenticated?
  end
end

If there were lots of resources I needed to provide exceptions to this way of making them would quickly become overwhelming. What is a better way to code this so I can make exceptions for the public directory or even its specific sub-directories and files like /stylesheets, /images, /images/bg.png but not /secret or /secret/eyes-only.pdf?

Or ... Is there a completely different best-practice to handle this situation of locking down everything except the stuff related to logging in (handlers, views, resources)?


You could extract the login logic into it's own Rack middleware (which can be a Sinatra app). The authentication middleware will serve the public files.

require 'sinatra'

class Authentication < Sinatra::Base
  def logged_in?
    # your login logic goes here
  end

  get '/login' do
    # login formular and logic here
  end

  get(//) do
    pass if logged_in?
    redirect '/login'
  end
end

configure { |c| c.use Authenitcation }

get('/') { ... }


Instead of putting the authorization information into your Sinatra application directly, why don't you extract it into Rack using Rack::Auth:

# my_app.ru



app = Rack::Builder.new do
  use Rack::Static, :urls => /^(stylesheets|javascripts|images|fonts)\//

  map '/login' do
    run MyApplication
  end

  map '/' do
    use Rack::Auth::Basic do |username, password|
      # check the username and password sent via HTTP Basic auth
    end
    run MyApplication
  end
end
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜