ruby - 在 Sinatra 中从全局身份验证中排除某些路径

标签 ruby authentication sinatra

我在 Sinatra 中有一个 API,使用中间件使用 token 进行全局限制身份验证。 该中间件在 before 语句中插入身份验证检查,以便全局保护所有内容,而无需在每个路由定义中添加检查。

before do
  denied unless
    authorized? or
    env['PATH_INFO'] == '/auth/login' or
    env['REQUEST_METHOD'] == 'OPTIONS' # For AngularJS headers checks
end

但现在我有一些路线需要从这个全局限制中排除(只有 2 或 3 个)并且不知道该怎么做。

我首先想到的是 Sinatra 条件:http://www.sinatrarb.com/intro.html#Conditions但由于它在之前的陈述中,我无法采取行动避免之前的情况。

然后我找到了这个解决方案:Before filter on condition

但这并不是一个真正干净的方法,而且它不能用于中间件和模块化 Sinatra 应用程序。

所以在搜索了很多之后,我需要一些帮助和建议。

如何做到这一点,可能需要帮助程序、条件和我的中间件中的一些修改?

最佳答案

为什么不把不需要授权的路由列表放到一个数组中检查呢?

configure do
  set :no_auth_neededs, ['/auth/login', "/a", "/b", "/c"]
end

before do
  denied unless
    authorized? or
    settings.no_auth_neededs.include?(env['PATH_INFO']) or
    env['REQUEST_METHOD'] == 'OPTIONS' # For AngularJS headers checks
end

我还没有测试过。


更新:

如果我花 10 秒的思考时间,我可以想到其他两种方法来做这件事,我的懒惰不会提示……但我很乐意相信直觉 :)

扩展 DSL

编写一个authorised_route处理程序:

require 'sinatra/base'

module Sinatra
  module AuthorisedRoute
    def authorised_route(verb,path,&block)
      before path do
        denied unless
          authorized? or
          request.request_method == 'OPTIONS' # For AngularJS headers checks
      end
      send verb.to_sym, path, &block
    end
  end

  register AuthorisedRoute
end

class API < Sinatra::Base
  register AuthorisedRoute

  authorised_route "get", "/blah" do
    # blah
  end

  get "/free-route" do
    # blah
  end
end

您可以删除那个 before block ,然后将逻辑放在路由中,YMMV。有很多方法可以使用这种东西。请注意将 env 替换为 request(参见 Accessing the Request Object)

See the docs for more on DSL extensions

使用类

将两种类型的路由分开,这就是类的用途,共享属性和/或行为的事物组:

require 'sinatra/base'

class AuthedAPI < Sinatra::Base

  before do
    denied unless
      authorized? or
      request.request_method == 'OPTIONS' # For AngularJS headers checks
  end

  # you should probably add the `denied` and `authorized?` helpers too

  # list of routes follow…
end

# define route that don't need auth in here
class OpenAPI < Sinatra::Base
  get "/auth/login" do
    # stuff…
  end
end

class API < Sinatra::Base
  use OpenAPI  # put OpenAPI first or a `denied` will happen.
  use AuthedAPI
end

然后将 API 映射到 rackup 文件中的 "/"(或任何 API 的根路径)。只有 AuthedAPI 中的路由会受制于 before block 。

关于ruby - 在 Sinatra 中从全局身份验证中排除某些路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25604380/

相关文章:

Ruby:如何使用 ']' 逃离正则表达式

ruby - 读取/分配实例变量的接受 block

ios - 使用 Apple 登录 : Possibility To Create Duplicate Account Issue

html - 将简单的 sinatra 应用程序转换为静态 html 页面的更好方法是什么?

javascript - Restangular:错误:未知提供者:RestangularProvider <- Restangular

sql - 使用 Chef 运行所有 sql 文件

python - Django:用户对象的 'email' 属性

c# - 使用 Auth header (如 webAPI 但在 MVC 中)进行身份验证

ruby - 我如何测试 Rack::Cache 是否在带有内存缓存的 Heroku 上与 Sinatra 应用程序一起运行?

ruby - 如何在模块化 Sinatra 应用程序中正确配置 ru。?