强制用户在首次使用 Devise 登录时重置密码

Are*_*epo 5 ruby-on-rails devise ruby-on-rails-4

[预计到达时间最后更新为我当前的解决方案]

我希望能够为高价值用户手动创建帐户,这意味着我们必须为他们生成密码并让他们在首次登录时更改密码。我在这里找到了执行此操作的解决方案,但它似乎是围绕 Devise 而不是使用它。

我当前的工作是覆盖 Devise ConfirmationsController 中的 #after_confirmation_path_for 方法,以便它包含以下代码片段:

if resource.sign_in_count == 1
  resource.send(:set_reset_password_token)
  edit_password_path(resource, reset_password_token: @token)
else
  # etc
end
Run Code Online (Sandbox Code Playgroud)

但是当它遵循该路径时,它会重定向远离密码更改,这似乎是因为 Devise::PasswordsController 中的这一行:

# Render the #edit only if coming from a reset password email link
append_before_filter :assert_reset_token_passed, only: :edit
Run Code Online (Sandbox Code Playgroud)

所以我可以覆盖那个调用,但我很担心它为什么在那里,以及这是否会导致其他问题 - 即使不会,感觉就像我正在做很多黑客工作来实现我想要的场景想象中是比较常见的。有没有一种更 Devise-y 的方法来解决这个问题?

ETA:我已经使用以下代码成功跳过了过滤器:

class PasswordsController < Devise::PasswordsController
  skip_before_filter :require_no_authentication,
                     :assert_reset_token_passed, 
                     only: :edit
end
Run Code Online (Sandbox Code Playgroud)

这在相关的用户旅程中有效,但这是一个验收测试相对较少的应用程序,因此我有点担心这会在其他地方产生连锁反应 - 比如意外地要求用户在其他用户旅程中更改密码。

任何人都可以建议使用这种方法是否正常,或者是否有更安全的替代方法?

Oth*_*sri 2

在您的应用程序控制器上,覆盖“after_sign_in_path”方法。使用sign_in_count来测试是否是首次登录:

def after_sign_in_path_for(resource)
 if current_user.sign_in_count == 1
  edit_passwords_path
 else
  root_path
 end
end
Run Code Online (Sandbox Code Playgroud)