在不创建Devise用户的情况下验证自定义策略

时间:2011-07-12 04:24:52

标签: ruby-on-rails authentication devise warden

我的设置:Rails 3.0.9,Ruby 1.9.2,Devise 1.3.4,Warden 1.0.4

我正在尝试确定是否可以对自定义策略进行身份验证,而不必在成功进行身份验证后在流程中创建设计用户。在我的config.warden块中,身份验证工作正常,但如果我不创建Devise用户,我将不会进行身份验证。我理想的情况要求我要么成功地对第三方提供商进行身份验证并登录我的应用程序(使用Devise而没有相应的Devise用户记录),或者如果我无法进行身份验证,请尝试设计标准登录路径。

这是我工作的devise.rb代码片段但是我必须创建一个设计用户才能使用身份验证,这是我希望避免的事情

config.warden do |manager|
    manager.strategies.add(:custom_strategy) do
      def valid?
        params[:user] && params[:user][:email] && params[:user][:password]
      end

      def authenticate!
        ...perform authentication against 3rd party provider...
        if successful_authentication
          u = User.find_or_initialize_by_email(params[:user][:email])
          if u.new_record?
            u.app = 'blah'
            u.save
          end
          success!(u)
        end
      end
    end

manager.default_strategies(:scope => :user).unshift :custom_strategy
  end

2 个答案:

答案 0 :(得分:0)

我希望这是针对设计的设计,其中所有操作都是使用资源的restful路径完成的。也就是说,Warden的success!方法中的评论说:

# Parameters:
#   user - The user object to login.  This object can be anything you have setup to serialize in and out of the session

那么你能否将对象u更改为代表用户的其他对象,就像普通的旧哈希一样?

答案 1 :(得分:0)

我意识到这个问题已经过时了,但是当我在寻找类似事情的解决方案时,我已经看了几次,所以我决定发布答案,以防将来有人遇到类似的问题。希望这会有所帮助!

我最近不得不做类似的事情 - >让我的数据库中的用户通过一些设计/ warden策略进行了身份验证,但创建了另一个必须访问我的应用程序的某些端点的应用程序。基本上我想做一个HMAC认证。 但是我不希望在该过程中涉及任何用户对象,这就是我必须做的事情(前提是您已经拥有自定义策略来验证传入请求而不使用用户对象)

  1. 创建一个假的用户模型,使用这样的设计,以便设计不会打击操作。您不必为该
  2. 创建任何数据库表 我看起来类似于下面的内容:

    class Worker # no need to create  a table for him
      extend ActiveModel::Callbacks
      extend Devise::Models
    
      include ActiveModel::Validations
      include Concerns::ObjectlessAuthenticatable
    
      define_model_callbacks :validation
    
      attr_accessor :id
    
      def persisted
        false
      end
    
      def initialize(id)
        @id = id
      end
    
      def self.serialize_from_session(id)
        self.new(id: id)
      end
    
      def self.serialize_into_session(record)
        [record.id]
      end
    
      def self.http_authenticatable
        false
      end
    end
    

    然后在设计初始化程序(/initializers/devise.rb)中我添加了单独的身份验证策略,如下所示:

      ...
      config.warden do |manager|
        manager.scope_defaults :user, :strategies => [
          ...strategies i was using for users
        ]
        manager.scope_defaults :worker, :strategies => [:worker_authentication], store: false, action: 'unautenticated_worker'
        manager.failure_app = CustomFailingApp
      end
      ...
    

    然后在routes.rb我必须为设计创建一个映射,如此

    devise_for :worker # you can pass some custom options here
    

    然后我需要验证工作人员,而不是我刚刚调用的用户(在控制器中)authenticate_worker!