设计重置密码电子邮件指向错误的控制器

Devise reset password email points to the wrong controller

我包括 devise_token_auth 以从别处托管的网络应用程序登录。但我也希望能够直接登录到我的 rails 应用程序。

我的 routes.rb 看起来像这样:

#...
devise_for :users

namespace :api, defaults: {format: :json} do
  mount_devise_token_auth_for 'User', at: 'auth'
  #...

要重置密码,webapp 会发送 POST/api/auth/password。通过上述配置,重置密码电子邮件中的 link 使用了错误的控制器(users/password 上的控制器)。 redirect_url 没有得到应用,用户看到的是 rails 应用程序的登录表单,而不是 web 应用程序:

http://localhost:3000/users/password/edit?redirect_url=http://localhost:8080/reset_password&reset_password_token=...

如果我评论行 devise_for :users 电子邮件 link 是正确的,使用 api/auth/password/edit:

http://localhost:3000/api/auth/password/edit?redirect_url=http://localhost:8080/reset_password&reset_password_token=...

当然,通过评论 devise_for :users 我无法仅使用 rails 应用程序(在 http://localhost:3000/users/sign_in 上)登录。

设计,在其邮件程序模板上重置密码 (reset_password_instructions.html.erb) 调用模型以获取 url:

<p><%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %></p>

尽管最初处理客户端重置密码意图的控制器是 DeviseTokenAuth::PasswordsControllerUser 上的函数 edit_password_url 解析为由 [=17= 处理的路径](users/password/edit 对比 api/auth/password/edit)。

本例中的解决方案是使用不同的模型:

routes.rb

#...
devise_for :users

namespace :api, defaults: {format: :json} do
  mount_devise_token_auth_for 'Api::User', at: 'auth'
  #...

api/user.rb

class Api::User < ActiveRecord::Base
   devise :database_authenticatable, :recoverable,
     :rememberable, :trackable, :validatable
   include DeviseTokenAuth::Concerns::User
   #...
end