我在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:我没有使用设计。
答案 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将停止运行策略。