我正在尝试使用Warden对基于JSON的API(Web服务)进行身份验证。我在config/initializers中定义了我的密码策略为password_strategy.rb,其中定义了authenticate!方法。当我从会话控制器的create方法中调用此authenticate!方法时,authenticate!中的参数不知何故变为空,即使我可以在会话控制器的create方法中看到我的参数。我不知道幕后发生了什么魔术。
由于我的参数为空,因此检测到我的身份验证未经授权,并将我重定向到会话新方法以再次登录,即使我的登录凭据是正确的。
这是我的代码:
我的post请求url:localhost:3000/login.json
参数:

{
  "emailID":"[email protected]",
  "encrypted_password":"XXXXXX"
}

# Sessions controller (sessions_controller.rb)
class SessionsController < ApplicationController
  skip_before_filter :authenticate!

  def new
    render :json => { :responseCode => "401",:responseMessage => "The email id or password you entered is incorrect. Please try again."}
  end

  def create
    authenticate!
    render :json => { :responseCode => "200",:responseMessage => "You have successfully logged in"}
  end
end

# Application Controller (application_controller.rb)
require 'globals_module.rb'

class ApplicationController < ActionController::Base
  include GlobalsModule

  prepend_before_filter :authenticate!

  helper_method :warden, :signed_in?, :current_user

  around_filter :wrap_in_transaction

  def wrap_in_transaction
    ActiveRecord::Base.transaction do
      yield
    end
  end

  def signed_in?
    !current_user.nil?
  end

  def current_user
    warden.user
  end

  def warden
    request.env['warden']
  end

  def authenticate!
    Rails.logger.info params[:emailID] # email ID is present
    Rails.logger.info params[:encrypted_password] #encrypted password is present
    warden.authenticate!
  end
end

# Password Strategy (password_strategy.rb in config/initializer)
class PasswordStrategy < Warden::Strategies::Base
  def authenticate!
    Rails.logger.info params # params are empty, although present before calling authenticate! method
    Rails.logger.info request.session["emailID"] # It's are empty either
    user = User.find_by_emailID(params[:emailID])
    # my authentication code goes here
  end
end

Warden::Strategies.add(:password, PasswordStrategy)

任何帮助都将不胜感激。提前谢谢。

最佳答案

您需要显式调用PasswordStrategy-通过将在Warden::Strategies.add中定义的命名符号作为第一个参数传递给authenticate,如下所示:

warden.authenticate!(:password)

或者在配置warden::manager(例如在config/application.rb中)时,将策略添加为默认值:
config.middleware.insert_after(ActionDispatch::Flash, Warden::Manager) do |manager|
    manager.default_strategies :password
end

完整的api请参见Warden Strategies Wiki
另请阅读integrating Warden with Rails without Devise,其中对典狱长的各个部分如何结合在一起有一个透彻的解释。

07-24 20:48