在 Devise with Rails3 中为密码重置查询添加子域条件?

发布于 2024-11-05 09:30:51 字数 1098 浏览 1 评论 0原文

我已经将 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 上注册,电子邮件地址为 [电子邮件受保护]
用户 2 在 company2.myapp.com 上注册,电子邮件地址为 [email  ;protected]

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

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

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

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

有更好的办法吗?

I've setup Devise (on Rails 3) to use Basecamp-style subdomain authentication. Under this model, a user could be registered twice under different subdomains with the same email address.

For example:

class User < ActiveRecord::Base
  belongs_to :account
end

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

User 1 registered on company1.myapp.com with email address [email protected]
User 2 registered on company2.myapp.com with email address [email protected]

(Both user account are controlled by the same human, but belong to different subdomains.)

Logging in works fine, but the standard Password Reset only looks up by email address, so you can only ever reset the password for User 1. What I'd like to do is take into account the request subdomain, so a password reset from company2.myapp.com/password/new would reset the password for User 2.

The Devise looks up the user using a find_first method, which I don't think accepts joins, so I can't include a :account => {:subodmain => 'comapny2'} condition.

I can reimplement send_reset_password_instructions to manually look up the user record, but it feels hacky and I'll need to do it for send_confirmation_instructions, too.

Is there a better way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

初与友歌 2024-11-12 09:30:51

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

根据我对源代码的阅读(我实际上还没有尝试过这一点),您可以添加一个 reset_password_keys 选项。这些应该包括子域。这会从 lib/devise/models/recoverable.rb。在 find_or_initialize_with_errors 中,它是仅这些键用于查找资源

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

更新:为了解决子域存储在帐户和用户belongs_to :account上的事实,您可以使用Rails 的 delegate 方法

It looks like this may be configurable with devise_for in the routes file.

From my reading of the source (and I haven't actually tried this), you can add a reset_password_keys option. These should include the subdomain. This is passed to find_or_initialize_with_errors from send_reset_password_instructions in lib/devise/models/recoverable.rb. In find_or_initialize_with_errors it's only these keys which are used to find the resource.

You'll probably also want to override Devise::PasswordsController#new template to include the user's subdomain when they submit the reset password request.

UPDATE: to address the fact that the subdomain is stored on Account and User belongs_to :account you can probably use Rails' delegate method.

无边思念无边月 2024-11-12 09:30:51

我们遇到了同样的问题。迈克·马祖尔的答案有效,但有一点不同:
我们把 :reset_password_keys =>; [:email, :subdomain] 在我们的 Users 模型中调用 devise 方法。

We experienced this same issue. Mike Mazur's answer worked, but for one difference:
We put :reset_password_keys => [:email, :subdomain] in the call to the devise method in our Users model.

空城仅有旧梦在 2024-11-12 09:30:51

我最近在 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

I recently implement this behaviour in a Rails 4 App.

…/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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文