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

发布于 2024-08-30 08:56:35 字数 755 浏览 2 评论 0原文

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

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

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

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:

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)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

若沐 2024-09-06 08:56:35

您可以将登录逻辑提取到它自己的 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('/') { ... }

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('/') { ... }
安静 2024-09-06 08:56:35

与其直接将授权信息放入您的 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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文