You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Devise重置密码邮件指向错误控制器,需保留Rails本地登录功能

解决Devise与Devise Token Auth共存时的密码重置链接问题

这个问题我之前也碰到过,核心是同时启用Devise的Web登录和Devise Token Auth的API登录时,两者的密码重置路由发生了优先级冲突,导致API请求触发的重置邮件错误使用了Web端的路由。下面给你两种可行的解决办法:

方法一:重写User模型的URL生成逻辑

这种方式可以根据请求来源自动切换重置链接,既保留Web端的正常功能,又确保API端生成正确的链接。

步骤1:修改User模型

在你的app/models/user.rb中添加重写方法:

class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
  include DeviseTokenAuth::Concerns::User

  # 重写重置密码URL生成方法
  def reset_password_url(token, opts = {})
    # 识别API请求(通过是否携带redirect_url参数判断)
    if opts[:redirect_url].present?
      # 使用API端的重置路由
      edit_api_auth_password_url(reset_password_token: token, redirect_url: opts[:redirect_url])
    else
      # Web端请求沿用Devise默认路由
      super(token, opts)
    end
  end
end

步骤2:保留原有路由配置

你的routes.rb不需要修改,继续保留两行配置:

devise_for :users
namespace :api, defaults: {format: :json} do
  mount_devise_token_auth_for 'User', at: 'auth'
end

方法二:自定义Devise Token Auth的邮件模板

如果你不想修改模型代码,也可以直接调整API端的邮件模板,强制使用API路由。

步骤1:生成Devise Token Auth的邮件视图文件

在终端执行以下命令,生成可自定义的邮件模板:

rails generate devise_token_auth:views

步骤2:修改重置密码邮件模板

找到生成的app/views/devise_token_auth/mailer/reset_password_instructions.html.erb(如果需要适配纯文本邮件,同时修改.text.erb文件),将其中的链接替换为API路由:

<p><%= link_to '重置密码', edit_api_auth_password_url(@resource.reset_password_token, redirect_url: @redirect_url) %></p>

这样所有通过API发起的密码重置请求,邮件都会生成正确的/api/auth/password/edit链接,而Web端发起的重置请求依然使用Devise默认的邮件模板和路由。

测试验证

完成配置后,记得分别测试两种场景:

  • 外部Web应用:发送POST请求到/api/auth/password,检查邮件链接是否指向API路由,且redirect_url参数有效,点击后跳转到外部应用的重置页面。
  • Rails Web应用:访问/users/sign_in确认登录功能正常,发起密码重置后,邮件链接应指向Web端的重置表单。

内容的提问来源于stack exchange,提问作者Baleato

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:50:49