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

使用自定义Mailer与authentication_keys的Devise无法发送重置密码邮件

排查重置密码无响应问题的解决方案

Hey there, let's break down this password reset issue you're facing—since your confirmation emails work perfectly, we can narrow the problem to specific parts of the reset flow. Here's step-by-step troubleshooting:

1. Fix the UserMailer Method Name (Critical Bug!)

Devise's recoverable module expects a method named reset_password_instructions to trigger password reset emails, but your code defines reset_user_password_instructions (extra user in the name). This means Devise can't find the method to send the email, so it silently renders the form again without feedback.

Update your UserMailer code:

def reset_password_instructions(record, token, opts={}) # Remove the extra "user" prefix
  browser = Browser.new
  @user = record
  @token = token
  self.template_model = {
    username: @user.username.try(:downcase),
    action_url: edit_user_password_url(@user, reset_password_token: @token),
    operating_system: browser.platform.name.try(:titleize),
    browser_name: browser.name.try(:titleize),
    support_url: 'xxx@xxx.com',
  }
  mail to: @user.email, postmark_template_alias: 'community_password_reset'
end

2. Configure Devise to Use Username for Password Resets

Your User model uses username as the authentication key, but Devise's recoverable module defaults to looking up users by email. This mismatch means Devise can't find the user when you submit the username, leading to the silent 200 response.

Add this line to config/initializers/devise.rb:

config.reset_password_keys = [:username]

This tells Devise to use the username field from your form to locate the user.

3. Verify Flash Message Rendering

Even if the flow works, you won't see feedback if your flash template isn't rendering correctly. Double-check layouts/_flash.html.erb includes code like this:

<% if notice %>
  <div class="alert alert-info"><%= notice %></div>
<% end %>
<% if alert %>
  <div class="alert alert-danger"><%= alert %></div>
<% end %>

Devise automatically sets a notice like "If your username exists in our database, you will receive a password reset link shortly."—this template ensures you see it.

4. Test Email Sending Manually

To confirm the mailer works outside the form flow, run this in your Rails console:

user = User.first
# Trigger Devise's full reset flow
user.send_reset_password_instructions
# Or test the mailer directly
UserMailer.reset_password_instructions(user, 'test_token').deliver_now

Check your Postmark dashboard to confirm the email was sent, and look for any errors in the Rails logs.

5. Ensure Proper Parameter Permissions

If you've customized the Users::PasswordsController, make sure it permits the username parameter:

class Users::PasswordsController < Devise::PasswordsController
  private
  def user_params
    params.require(:user).permit(:username, :email, :password, :password_confirmation)
  end
end

Why Confirmation Emails Worked

Your confirmation flow uses the correct method name (confirmation_instructions) that matches what Devise's confirmable module expects, so that part of your setup was already correct.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 19:32:42