Sinatra:我如何提供对登录表单的访问,同时阻止访问我的Sinatra应用程序的其余部分?

时间:2010-04-22 15:08:20

标签: ruby sinatra

我最近创建了一个带登录表单的Sinatra应用程序(没有基本身份验证)。为了防止访问应用程序,除非用户登录,我放置了一个前一块

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

我很快意识到,这使我无法访问公共目录中的资源,例如我的样式表和徽标,除非首先进行身份验证。为了解决这个问题,我将过滤器更改为以下内容:

before do
  unless request.path_info == '/login' || request.path_info == "/stylesheets/master.css" || request.path_info == "/images/logo.png"
    authenticated?
  end
end

如果有很多资源我需要提供例外,这种方式很快就会变得无法应对。什么是更好的代码编码方式,以便我可以为公共目录甚至其特定的子目录和文件(例如/stylesheets/images/images/bg.png而不是{{1} }或/secret

或者......是否存在完全不同的最佳实践来处理锁定除登录(处理程序,视图,资源)相关内容之外的所有事情?

2 个答案:

答案 0 :(得分:1)

您可以将登录逻辑提取到自己的Rack中间件(可以是Sinatra应用程序)中。 身份验证中间件将提供公共文件。

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('/') { ... }

答案 1 :(得分:0)

不是直接将授权信息放入Sinatra应用程序,为什么不使用Rack::Auth将其提取到Rack中:

# 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