设计确认在首次发送时无效

2024-01-07

我有一个 Rails 4 应用程序,使用 Devise 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>

据我所知,一切都是相当标准的费用,而且它仅在最初创建时失败而不是在重新发送时失败这一事实相当令人困惑。

- 更新 -

单击该链接时,我会在开发日志中看到以下内容:

Started GET "/account/confirm?confirmation_token=3bQP-EvYJPv74s9AMz63" for 127.0.0.1 at 2014-02-07 12:26:10 -0500
Processing by Users::ConfirmationsController#show as HTML
  Parameters: {"confirmation_token"=>"3bQP-EvYJPv74s9AMz63"}
  User Load (0.4ms)  SELECT "users".* FROM "users" WHERE "users"."confirmation_token" = 'e191b48746f15014beb32073f08de3c7aa13a2282216f089fa71d083901b3dca' ORDER BY "users"."id" ASC LIMIT 1
  Rendered devise/shared/_links.slim (1.2ms)
  Rendered devise/confirmations/new.html.slim within layouts/devise (7.0ms)
  Rendered layouts/_jquery.slim (1.0ms)
Completed 200 OK in 32ms (Views: 23.4ms | ActiveRecord: 0.4ms)

引用的控制器是:

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

-- 更新2 --

以下是整个注册过程的日志要点:https://gist.github.com/jbender/bbe079c2dd3fa2d1e664 https://gist.github.com/jbender/bbe079c2dd3fa2d1e664


看起来有些东西导致您的用户在注册之前立即更新并重新保存(包括生成新的确认令牌)create行动已完成。看看你的要点:

  • 第 5 行显示设备使用电子邮件地址检查现有用户
  • 第 6 行显示了检查刚刚生成的确认令牌是否已存在于其他用户的设计(显然它们需要是唯一的)
  • 第 9 行显示正在插入数据库的新用户记录
  • 第 11 行看起来 devise 刚刚生成了一个新的确认令牌,并且正在检查这个新令牌是否已在使用中。
  • 第 14 行显示正在保存的更新后的用户详细信息,包括这个新的确认令牌。我注意到有一个 tos_accepted_at 字段在第 9 行的初始插入中不存在。 unconfirmed_email 字段也已设置,并且confirmation_sent_at 字段比第 9 行中保存的字段晚 1 秒;这可能只是由于正常的 :confirmable 行为,尽管我很惊讶 devise 没有意识到电子邮件地址与现有(未经确认)的电子邮件地址相同并且不打扰这一事实。

问题是为什么用户会被保存两次?看起来您已经添加了 tos_accepted_at 属性。是否有一些代码(后置过滤器?)重新保存用户,包括此属性以及所有其他属性,然后再次触发设计的可确认逻辑?说到这里,我最感兴趣的是,考虑到confirmation_sent_at时间戳发生了变化,它并没有立即导致发送第二封电子邮件(带有有效的确认令牌)。

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

作为额外的健全性检查,如果您可以猛击 Rails 控制台来加密您期望的确认令牌,您会发现加密版本与要点第 6 行的版本匹配,然后在数据库中覆盖第 9 行。我无法尝试此操作,因为它取决于您的 Rails 秘密(请参阅 devise/toekn_generator.rb 中的 Devise::TokenGenerator)。无论如何,没有必要,但会确认原始的确认令牌永远不会起作用。

我认为重新发送有效,因为这只是正常情况(没有双重保存,没有额外的 tos_accepted_at 字段等)

UPDATE

正如评论中所讨论的,问题确实是 tos_accepted_at 属性。它正在使用更新update_attribute() in an after_create打回来。由于有点不清楚的原因,这似乎弄脏了所有属性,所以它们也都被保存了(update_attribute还保存所有其他属性(如果它们是脏的)并设计生成一个新的确认令牌作为此过程的一部分(尽管我们认为它不应该具有,因为电子邮件地址实际上并未更改!)。更改保存更新的过滤器tos_accepted_at to a before_save过滤而不是after_create通过确保用户只保存一次来避免这个问题,因为before_save显然发生在第一次保存之前,而不是after_create这当然发生在将用户插入数据库的保存之后。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

设计确认在首次发送时无效 的相关文章

随机推荐

  • 使用 matplotlib 在 qiskit 中可视化电路

    我正在学习如何使用 qiskit 并且正在使用 jupyter 笔记本 但是每次我尝试使用属性绘制来可视化电路时 我都会收到此错误 import qiskit from qiskit import from qiskit import IB
  • 如何在 Linux、Mac 和 Windows 上从 Java 启动 .NET 应用程序?

    我想从 Java 环境的上下文中启动 NET 应用程序 与 Mono 兼容 我的猜测是 我必须以某种方式确定是否安装了 mono 找到位置并使用 NET 应用程序路径作为参数启动它 但什么是可靠的方法呢 或者 还有更好的方法 也许我应该澄清
  • 按HOME后重新启动应用程序时如何返回到最新启动的活动? [复制]

    这个问题在这里已经有答案了 熟悉的场景 我有一个Main启动的活动Game按下按钮时的活动 如果用户按 HOME 然后再次启动我的应用程序 则应显示GameActivity 这是他最后一次使用该应用程序时所做的事情 然而 相反发生的事情是他
  • 为什么 div 会有这样的行为?

    有时我的 div 会出现这个问题 无法按预期运行 我想要的是让它们按照我的理解 流动 布局 但它们不是 我只是想知道为什么不 我已经使用 firebug 来检查 css 似乎没有任何不符合规范的内容 但它们并没有一个接一个地流动 我提供了两
  • 在领域驱动设计中,您可以在 UI 中使用领域实体吗?

    在许多领先的 DDD 项目中 尤其是 MVC 风格 我看到 UI 使用镜像域实体的显示对象 而不是直接使用这些域对象 这种风格显然是为了解耦和分离关注点 我个人更喜欢这种风格 但我不确定这是否是 DDD 的严格原则 或者这是否只是不同开发人
  • 我需要做直方图拉伸

    我有一个 BitmapFrames 数组 需要进行直方图拉伸 我知道这与直方图均衡不同 最终结果是什么 有点 问题是我完全不知道得到直方图后该怎么做 到目前为止 我的代码为直方图创建了一个数组 因此我知道每个值有多少个像素 但在那之后我不知
  • 让semantic_errors呈现准确的错误消息

    我有一个模型Camping which has many Images 露营至少需要一张图片 class Camping lt ActiveRecord Base attr accessible images attributes has
  • PostgreSQL:如何实现最小基数?

    正如这个问题中的回答 PostgreSQL 中的基数 https stackoverflow com questions 3135206 cardinality in postgresql 基数是使用强制执行的限制条件 http www p
  • 使用游标获取字段值

    我正在创建一个应用程序 但遇到问题Cursor 我有一个SQLiteDatabase这给我返回了一个Cursor当我尝试使用此函数获取值时 public Cursor fetchOption long rowId throws SQLExc
  • 如何将“zd”说明符与“printf()”一起使用?

    寻求有关使用的说明 zd with printf 当然 对于 C99 及更高版本 以下内容是正确的 void print size size t sz printf zu n sz C 规范seems允许printf zd n sz 取决于
  • 如何正确对齐此文本?

    我今天写了这个极地时钟 我几乎完成了 除了我想在行内对齐我的文本 类似于this http blog pixelbreaker com polarclock 有谁知道如何做到这一点 我尝试使用 FontRenderContext 和字体指标
  • Android HttpClient 性能

    我正在开发 Android 应用程序 它使用大量对 Web 服务的 http 请求 起初 我在每个请求之前创建一个新的 HttpClient 实例 为了提高性能 我尝试在多个线程中执行请求 因此 我使用 ThreadSafeConnecti
  • 带有 c:foreach jstl 标签的二维数组列表

    我在两个叠瓦式 JSTL 中使用二维数组列表
  • 计算多个 CSV 文件中一列的平均值

    我的文件夹中有 300 多个 CSV 文件 名为 001 csv 002 csv 等 每个包含一个带有标题的数据帧 我正在编写一个函数 该函数将采用三个参数 文件的位置 要计算平均值的列的名称 数据框内 以及计算中使用的文件 这是我的功能
  • 如何在 Eclipse 中调试在 jetty 上运行的 Web 应用程序?

    以前从未做过网络编程 有没有办法设置断点 在 Eclipse 中查看变量值 我想要调试的应用程序会生成一个我想轻松提取的查询字符串 单击外部工具配置 Select program and click the new button top l
  • 无法将 React.lazy 与 Material UI 图标一起使用

    因为我的应用程序中的很多地方都有很多图标 所以我想对它们使用代码分割 我创建了辅助组件来执行此操作 import React FunctionComponent Suspense from react interface LazyMuiIc
  • 在哪里可以找到 Google Compute Engine 的名称服务器?

    我已将一个网站上传到我的 Compute Engine 实例 并且我想设置注册器以将访问者发送到服务器 Compute Engine 在哪里可以通过 Compute Engine 获取实例 服务器的名称服务器 Google Compute
  • 使用 alex/happy 与 Cabal

    我正在为我正在学习的课程编写一个编译器 该类不是专门的 Haskell 但我使用 Haskell 来编写我的编译器和解释器 我有一个 cabal 包设置 希望能让我的教授轻松运行 编译 我有快乐和亚历克斯在build tools两个可执行文
  • node.js - 配置节点将函数加载到全局范围内?

    在现实生活中 我在某个地方看到我们可以配置 Node js 在全局范围内执行加载的模块 但我现在找不到如何做到这一点 我为什么要问 我有一些遗留文件定义了我想在服务器和客户端上使用的语言实用程序 但是其中许多实用程序被定义为全局范围函数 例
  • 设计确认在首次发送时无效

    我有一个 Rails 4 应用程序 使用 Devise 3 2 2 confirmable 并且遇到了发送无效确认令牌的问题 但是只是第一次 重新发送确认令牌后 链接将起作用 相关路线 devise for users skip sessi