Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/53.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 设计确认在第一次发送时无效_Ruby On Rails_Devise_Ruby On Rails 4_Devise Confirmable - Fatal编程技术网

Ruby on rails 设计确认在第一次发送时无效

Ruby on rails 设计确认在第一次发送时无效,ruby-on-rails,devise,ruby-on-rails-4,devise-confirmable,Ruby On Rails,Devise,Ruby On Rails 4,Devise Confirmable,我有一个Rails 4应用程序,带有Desive 3.2.2,使用了:confirmable,我遇到了一个问题,因为它发送了无效的确认令牌,但是只是第一次。重新发送确认令牌后,链接将工作 有关路线: devise_for :users, skip: [:sessions, :passwords, :confirmations, :unlocks, :registrations, :invitations] as :user do ... # joining get '/regis

我有一个Rails 4应用程序,带有Desive 3.2.2,使用了
:confirmable
,我遇到了一个问题,因为它发送了无效的确认令牌,但是只是第一次。重新发送确认令牌后,链接将工作

有关路线:

devise_for :users, skip: [:sessions, :passwords, :confirmations, :unlocks, :registrations, :invitations]
as :user do
  ...
  # joining
  get   '/register' => 'devise/registrations#new',    as: 'new_user_registration'
  post  '/register' => 'devise/registrations#create', as: 'user_registration'
  ...
end
…以及相关的邮件模板:

<p>Welcome <%= @email %>!</p>

<p>You can confirm your account email through the link below:</p>

<p><%= link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @token) %></p>
引用的控制器是:

class Users::ConfirmationsController < Devise::ConfirmationsController

  protected

  def after_confirmation_path_for(resource_name, resource)
    if signed_in?
      signed_in_root_path(resource)
    else
      new_session_path(resource_name, email: resource.email)
    end
  end

end
class用户::确认控制器
--更新2--

以下是整个注册过程中的日志要点:

根据路由文件,我假设您已覆盖注册控制器。
我的直觉是你在注册时做了一些不正确的事情#创建操作。具体而言,在创建确认令牌时,该令牌未正确存储在用户记录中

我的理论是:

  • 第278行 返回false,因为第277行找不到具有提供的令牌的用户,因为该令牌未正确存储。277因此创建一个新的用户记录,278返回
    false

  • 当您完成重新发送过程时,整个令牌生成/存储过程将在la和确认中再次完成。这修复了注册#创建中遗漏的存储步骤


  • 在初始创建时,您能否验证确认令牌是否正确存储在您的用户模型上

    在注册
    create
    操作完成之前,似乎有什么原因导致您的用户立即更新并重新保存(包括生成新的确认令牌)。看看你的要点:

    • 第5行显示使用电子邮件地址对现有用户进行设计检查
    • 第6行显示designe检查它刚刚生成的确认令牌是否已经存在于其他用户(显然它们需要是唯一的)
    • 第9行显示插入数据库的新用户记录
    • 第11行看起来Deviate刚刚生成了一个新的确认令牌,正在检查这个新令牌是否已经在使用中
    • 第14行显示了正在保存的更新的用户详细信息,包括这个新的确认令牌。我注意到有一个tos_accepted_at字段,它在第9行的初始插入中不存在。未确认电子邮件字段也已设置,确认发送字段比第9行中保存的字段晚1秒;这可能只是由于正常的:可确认的行为,尽管我很惊讶Desive没有发现电子邮件地址与现有的(未确认的)电子邮件地址相同这一事实,也不麻烦
    问题是为什么用户被保存了两次?看起来您已经添加了tos_accepted_at属性。是否有一些代码(后过滤器?)重新保存用户,包括此属性以及所有其他属性,然后再次触发Desive的可确认逻辑?说到这一点,我最感兴趣的是,它没有立即导致发送第二封电子邮件(带有有效的确认令牌),因为时间戳上发送的确认发生了变化

    我注意到一些版本跟踪也在进行中,从其他插入判断,尽管看起来这不会造成干扰

    作为一个附加的健全性检查,如果您可以强制rails控制台加密您期望的确认令牌,您会发现加密的版本与gist第6行的版本匹配,然后在db第9行被覆盖。我不能尝试这个,因为这取决于您的rails机密(请参阅designe/toekn_generator.rb中的designe::TokenGenerator)。无论如何,这不是必需的,但会确认原始确认令牌永远不会工作

    我认为重发是有效的,因为这只是正常情况(没有双重保存,没有额外的tos_在字段中接受等)

    更新


    正如在评论中所讨论的,问题确实是tos_accepted_at属性。在创建后的
    回调中使用
    update\u attribute()
    对其进行更新。出于一些不清楚的原因,这似乎弄脏了所有属性,因此它们也都被保存了(
    update\u attribute
    还保存了所有其他属性,如果它们脏了),Desive生成了一个新的确认令牌作为此过程的一部分(尽管我们认为不应该这样做,因为电子邮件地址实际上没有更改!)。将保存更新后的
    tos\u accepted\u(在
    处)的过滤器更改为保存前的
    过滤器,而不是创建后的
    ,通过确保用户只保存一次,避免了该问题,因为
    before\u save
    显然发生在第一次保存之前,而不是
    before\u create
    之后,后者当然发生在将用户插入数据库的保存之后。

    1)我没有覆盖注册控制器,只是更改了路径(他们仍然要
    设计/注册#创建
    )2)用户正在正确保存,并按预期包含令牌:
    根据开发日志,状态为
    Completed 200 OK
    ,因此我假设此日志用于
    Users::confirmationcontroller#show
    操作的重新发送确认。您是否可以共享第一次生成的确认电子邮件令牌链接内容,然后在单击相同内容时共享日志,以便我们可以分析数据。不,这是第一次尝试(失败)时的日志。发布的日志消息会导致显示“无效令牌”错误,即使其状态为200。创建时会验证
    tos\u协议,创建后会验证
    以更新它(用户
    
    class Users::ConfirmationsController < Devise::ConfirmationsController
    
      protected
    
      def after_confirmation_path_for(resource_name, resource)
        if signed_in?
          signed_in_root_path(resource)
        else
          new_session_path(resource_name, email: resource.email)
        end
      end
    
    end