【问题标题】:Add a subdomain condition to password reset query in Devise with Rails3?使用 Rails3 在 Devise 中向密码重置查询添加子域条件?
【发布时间】:2011-05-05 12:33:12
【问题描述】:

我已将 Devise(在 Rails 3 上)设置为使用 Basecamp 样式的子域身份验证。在这种模式下,用户可以使用相同的电子邮件地址在不同的子域下注册两次。

例如:

class User < ActiveRecord::Base
  belongs_to :account
end

class Account < ActiveRecord::Base
  # subdomain attribute stored here
end

用户 1 在 company1.myapp.com 上注册,电子邮件地址为 bob@acme.com
用户 2 在 company2.myapp.com 上注册,电子邮件地址为 bob @acme.com

(两个用户帐号都由同一个人控制,但属于不同的子域。)

登录工作正常,但标准密码重置仅通过电子邮件地址查找,因此您只能重置 用户 1 的密码。我想做的是考虑请求子域,因此从 company2.myapp.com/password/new 重置密码将重置 用户 2 的密码。

Devise 使用 find_first 方法查找用户,我认为该方法不接受连接,因此我不能包含 :account =&gt; {:subodmain =&gt; 'comapny2'} 条件。

我可以重新实现send_reset_password_instructions 来手动查找用户记录,但感觉很麻烦,我也需要为send_confirmation_instructions 这样做。

有没有更好的办法?

【问题讨论】:

    标签: ruby-on-rails devise


    【解决方案1】:

    看起来这可以通过路由文件中的devise_for 进行配置。

    根据我对源代码的阅读(实际上我还没有尝试过),您可以添加一个reset_password_keys 选项。这些应该包括子域。这从send_reset_password_instructions 中的lib/devise/models/recoverable.rb 传递给find_or_initialize_with_errors。在find_or_initialize_with_errors 中是only these keys which are used to find the resource

    您可能还希望在用户提交重置密码请求时覆盖 Devise::PasswordsController#new 模板以包含用户的子域。

    更新:为了解决子域存储在帐户和用户belongs_to :account 上的问题,您可以使用Rails' delegate method

    【讨论】:

    • 您对 reset_password_keys 选项是正确的,但这将作为用户模型的条件传入。我将子域存储在 Account 模型(用户属于_to)上,因此通过 reset_password_keys 传递它似乎不起作用。
    • 我刚刚重新阅读了我原来的问题并意识到我的代码示例不正确 - 我调用了 Account 模型 User,这没有意义。现已修复。
    • 好的,不用担心。我更新了我的答案,希望能帮到你。
    【解决方案2】:

    我们遇到了同样的问题。 Mike Mazur 的回答有效,但有一个区别: 我们将:reset_password_keys =&gt; [:email, :subdomain] 放在对用户模型中devise 方法的调用中。

    【讨论】:

      【解决方案3】:

      我最近在 Rails 4 应用程序中实现了这种行为。

      …/config/initializers/devise.rb

      (…)
      # ==> Configuration for :recoverable
      #
      # Defines which key will be used when recovering the password for an account
      config.reset_password_keys = [:email, :subdomain]
      (…)
      

      …/app/views/devise/passwords/new.html.erb

      (…)
      <%= f.input :subdomain, required: true %>
      (…)
      

      …/app/controllers/users/passwords_controller.rb

      class Users::PasswordsController < Devise::PasswordsController
      
        def resource_params
          params.require(:user).permit(:email, :subdomain, ...)
        end
      
        private :resource_params
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-08-19
        • 1970-01-01
        • 1970-01-01
        • 2013-05-19
        • 2011-05-31
        • 2012-09-23
        相关资源
        最近更新 更多