2010-04-22 2 views
2

Недавно я создал приложение Sinatra с формой входа (без базового auth). Для того, чтобы предотвратить доступ к приложению, если пользователь не вошел в я положил перед блочным вместо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, но не /secret или /secret/eyes-only.pdf?

Или ... Есть ли совершенно другая передовая практика, позволяющая справиться с этой ситуацией, блокируя все, кроме материалов, связанных с входом в систему (обработчики, представления, ресурсы)?

ответ

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

вы блокируете только запросы на получение, а не отправляете или помещаете и т. Д. Поместите 'redirect '/ login', если вместо request.path == '/ login' или logged_in?' Вместо 'before' –

0

Вместо того, чтобы информация об авторизации в приложение Sinatra непосредственно, почему вы не извлечь его в стойку с помощью 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

@james Я думаю, ваше предложение заставит мое приложение использовать базовый auth (стандартное диалоговое окно браузера, представленное пользователю), которое обычно является отличным решением, но для этого конкретного приложения я должен представить пользователю ** html form ** для входа, где они могут ввести имя пользователя и пароль в поля ввода и нажать кнопку отправки. – caspyin

+0

В этом случае я предлагаю просто использовать другое промежуточное ПО. Он все равно вернет 401 Unauthorized, но не будет использовать заголовок «WWW-Authenticate: Basic» и будет включать тело. Это в значительной степени эквивалентно предложению Константина использовать отдельное приложение Sinatra в качестве промежуточного программного обеспечения. –

Смежные вопросы