我最近创建了一个带登录表单的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
?
或者......是否存在完全不同的最佳实践来处理锁定除登录(处理程序,视图,资源)相关内容之外的所有事情?
答案 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