【问题标题】:Authenticate custom strategy without creating Devise user在不创建设计用户的情况下验证自定义策略
【发布时间】:2011-07-12 04:24:51
【问题描述】:

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

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

这是我开始工作的 devise.rb 代码 sn-p 但我必须创建一个设计用户才能进行身份验证,这是我希望避免的事情

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

【问题讨论】:

标签: ruby-on-rails authentication devise warden


【解决方案1】:

我意识到这个问题很老,但我在寻找类似问题的解决方案时看到了几次,所以我决定发布答案,以防将来有人偶然发现类似问题。希望这会有所帮助!

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

  1. 创建一个假的用户模型,以便设计不会破坏操作。您不必为此创建任何数据库表

我的看起来类似于下面:

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!

【讨论】:

  • 如果你需要一个例子,这种无用户认证策略应该是什么样子,我也可以提供代码
【解决方案2】:

我希望这与设计的设计相悖,在该设计中,所有操作都使用资源的静止路由完成。也就是说,Warden 的 success! 方法中的 cmets 说:

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

那么你能不能将对象u 更改为代表用户的其他对象,比如普通的旧哈希?

【讨论】:

    猜你喜欢
    • 2014-10-12
    • 2011-05-12
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 1970-01-01
    • 2014-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多