使用Grape API应用程序配置Warden

时间:2014-10-24 13:49:51

标签: ruby-on-rails warden grape-api

我已在config/initializers/warden.rb中的Rails / Grape API应用中配置了Warden:

Rails.application.config.middleware.use Warden::Manager do |manager|
  manager.default_strategies :password
end

(我分享password策略代码,但它确实不适用于此问题。我将其存储在config/initializers/warden/strategies/password.rb。)

当我使用无效的登录凭据运行RSpec rquest规范时:

describe 'session_tokens', type: :request do
  let!(:user)      { FactoryGirl.create(:user) }
  let(:ip_address) { Faker::Internet.ip_v4_address }

  describe 'POST /' do
    context 'with invalid password' do
      before do
        post '/api/v1/session_tokens', email: user.email, password: "#{user.password}.", ip: ip_address
      end

      it 'is unsuccessful' do
        expect(response.code).to eql '401'
      end

      it 'has an "X-Error-Detail" header' do
        expect(response.header['X-Error-Detail']).to eql 'Invalid email or password.'
      end
    end
  end
end

它给了我这个错误:

Failure/Error: post '/api/v1/session_tokens', email: user.email, password: "#{user.password}.", ip: ip_address
RuntimeError:
   No Failure App provided

对于我的生活,在线查看示例后,我无法让Warden与Grape一起正常工作(例如,dblock/grape_warden)。大多数示例都很简单,并将Grape应用程序本身设置为失败应用程序。

当我在我的Grape应用程序中传递模块failure_app

Rails.application.config.middleware.use Warden::Manager do |manager|
  manager.default_strategies :password
  manager.failure_app = -> (env) { API::V1::SessionTokens }
end

我收到此错误,即使我在该模块中有post :unauthenticated块:

Failure/Error: post '/api/v1/session_tokens', email: user.email, password: "#{user.password}.", ip: ip_address
NoMethodError:
  undefined method `unauthenticated' for API::V1::SessionTokens:Class

当我将unauthenticated定义移动到我的Grape应用程序的根目录时,会发生同样的情况。

1 个答案:

答案 0 :(得分:2)

解决方案是在Grape应用程序本身内配置Warden,而不是在Rails初始化程序中配置。

我删除了config/initializers/warden.rb并将其内容放入我的Grape应用中:

module API
  module V1
    class Base < Grape::API
      mount API::V1::SessionTokens

      use Warden::Manager do |manager|
        manager.default_strategies :password
        manager.failure_app = API::V1::SessionTokens
      end
    end
  end
end

现在完美运作!

尤其感谢Jean Bahnik this file on GitHub。几乎放弃后,我发现了这段漂亮的代码。