守望者跳过策略

时间:2017-05-26 23:41:26

标签: ruby-on-rails ruby warden

我在Rails API应用程序中有两个warden策略,用于基本身份验证和令牌身份验证。

初始化/ warden.rb

Warden::Strategies.add(:auth_token, AuthTokenStrategy)
Warden::Strategies.add(:basic_auth, BasicAuthStrategy)

配置/ application.rb中

config.middleware.insert_after ActionDispatch::Callbacks, Warden::Manager do |manager|
  manager.default_strategies :auth_token, :basic_auth
  manager.failure_app = UnauthorizedController
end

这两种策略都实现了#valid?

class BasicAuthStrategy < ::Warden::Strategies::Base
  def valid?
    auth.provided? && auth.basic?
  end
  ...
end

class AuthTokenStrategy < ::Warden::Strategies::Base
  def valid?
    auth.provided? && !auth.basic? && headers['HTTP_AUTHORIZATION'].start_with?('Bearear')
  end
  ...
end

我想用令牌发出请求,warden尝试BasicAuthStrategy然后尝试AuthTokenStrategy mas它在第一个之后结束。它忽略了一种策略。为什么呢?

PS:我没有使用设计。

1 个答案:

答案 0 :(得分:0)

首先,我假设auth.provided?auth.basic?已定义且工作正常。您提供的示例未显示authenticate!方法的外观,因此我将添加一些伪代码。

class AuthTokenStrategy < ::Warden::Strategies::Base
  def valid?
    request.headers['HTTP_AUTHORIZATION'].start_with?('Bearear')
  end

  def authenticate!
    bearer_token = request.headers['HTTP_AUTHORIZATION'].split(' ')
    if user = User.find_by(bearer_token: auth_token)
      success!(user)
    end
  end
end

class BasicAuthStrategy < ::Warden::Strategies::Base
  def valid?
    not request.headers['HTTP_AUTHORIZATION'].nil?
  end

  def authenticate!
    auth_token = request.headers['HTTP_AUTHORIZATION']
    if user = User.find_by(auth_token: auth_token)
      success!(user)
    end
  end
end

Warden::Strategies.add(:auth_token, AuthTokenStrategy)
Warden::Strategies.add(:basic_auth, BasicAuthStrategy)

Rails.application.config.middleware.use Warden::Manager do |manager|
  manager.default_strategies %i[auth_token basic_auth]
  # manager.failure_app = lambda { |env|
  #  SessionsController.action(:failure).call(env)
  #}
end

值得注意的是,在您的情况下,valid?定义可能是可选的。当一个人返回success!时,Warden将停止运行策略。