2017-05-26 1 views
1

J'ai deux stratégies de garde dans une application Rails API, pour l'authentification de base et pour l'authentification par jeton.Warden saute la stratégie

initializers/warden.rb

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

config/application.rb

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

Et les deux stratégies met en œuvre #valid?

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

et

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

J'imagine faire une demande avec jeton, gardien tente BasicAuthStrategy puis il essaie AuthTokenStrategy mas se termine après la première. Il ignore une stratégie. Pourquoi?

PS: Je n'utilise pas concevoir.

Répondre

0

D'abord je supposerai que auth.provided? et auth.basic? sont définis et fonctionnent correctement. L'exemple que vous avez fourni ne montre pas à quoi ressemble la méthode authenticate! donc je vais mettre du pseudo-code.

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 

Il convient de noter que, dans votre cas, la définition valid? peut être facultative. Warden cessera d'exécuter des stratégies quand on renverra success!.