我有一个安装在 Rails 应用程序下的 Sinatra 应用程序/admin
。Sinatra 应用程序是一个管理仪表板,因此应该只对授权用户可用。
为了强制执行,我构建了一个 Rack Middleware,它将在调用 Sinatra 应用程序之前运行。
逻辑很简单——
- 如果用户通过身份验证,则照常继续
- 如果用户未通过身份验证,请使用 flash 警报消息重定向到根路径(我正在使用rack-flash gem 来允许访问 Rack 中的 flash 消息)
代码如下。我觉得我在redirect
方法中遗漏了一些东西。该Rack::Builder
块构造了一个迷你机架应用程序,内部块进一步创建另一个机架应用程序(Proc),该应用程序使用闪存消息构建重定向响应。
当我运行它时,我得到undefined method 'detect' for nil:NilClass
,这表明两个块都没有返回有效的非nil
响应。我需要call
在这些块之一上的某个地方运行吗?
如果有帮助,我正在使用 Puma Webserver。
谢谢!
require "rack"
require "rack-flash"
class AdminAuthorizer
def initialize(app)
@app = app
end
def call(env)
@env = env
id = @env["rack.session"][:user_id]
user = User.where(id: id).first
# Check if user is authorized, otherwise redirect
user.admin? ? ok : redirect
end
private
def ok
@app.call(@env)
end
def redirect
Rack::Builder.new do
use Rack::Flash, sweep: true, accessorize: true
run(
Proc.new do |env|
env["x-rack.flash"].alert = "Insufficient permissions"
res = Rack::Response.new
res.redirect("/")
res.finish
end
)
end
end
end