我在Sinatra中有一个API,使用一个中间件对令牌执行全局限制身份验证。
此中间件在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语句中,我无法在之前采取行动避免它。
然后我找到了这个解决方案: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块,把逻辑放在路由中,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块。

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

10-11 04:06
查看更多