2

我正在为 Rails 应用程序编写一个非常简单的邮件系统。我正在使用 RESTful 身份验证。这是一个相当传统的设置,当用户注册和忘记密码时,我会发送相同的电子邮件。我只是遇到了一个我似乎无法解决的问题。

我想对这两个实例使用相同的电子邮件模板,即使“新用户”电子邮件将来自用户控制器,而“忘记密码”电子邮件将来自密码控制器。

电子邮件看起来像这样:

<%=h @user.name %>, 
Your membership details:
Username: <%=h @user.login %>
Password: <%=h @user.password %>

当用户注册时,这工作得很好,导致一封看起来像这样的电子邮件:

  Bryan,
  Your membership details:
  Username: bryan
  Password: password

不幸的是,当尝试使用此模板从密码控制器发送“忘记密码”电子邮件时,一切都会中断。然而,令我困惑的是,它只是有点中断:

  Bryan,
  Your membership details:
  Username: bryan
  Password: 

换句话说,@user.name 仍然有效,@user.login 也是如此。但是由于某种原因,在这种状态下@user.password 没有通过。

感谢您的回复。需要明确的是,在这种情况下,安全性确实不是问题,因此,能够以纯文本形式发送忘记的密码而不是通过重置密码过程会更好,但我很感激这一点通常情况并非如此。

4

6 回答 6

2

如果没有看到您的一些代码,特别是控制器方法,很难说。

尽管注册电子邮件可能在加密之前使用了密码。未加密的密码通常不可用于以后的操作,因为它已加密存储在 db 中。

但是,如果您的密码控制器正在设置新密码,而不是尝试检索旧密码,那么问题很可能出在其他地方。

无论如何,这就是人们在不看代码的情况下所能做的尽可能多的猜测。

于 2009-04-08T23:15:29.040 回答
1

如果您查看数据库,您将看到密码哈希和盐哈希。

在将明文密码存储到数据库之前,您必须将明文密码存储在另一个变量中,使用带有明文密码的单独变量,您可以将其传递给 ActiveMailer 并在没有加密的情况下在电子邮件中发送。

@user = User.find(params[:id])
password = params[:user][:password]
options = {
    :password => password,
    :user => @user
}

if @user.update_attributes(params[:user]) and Mailer.deliver_reset(options)
    flash[:notice] = "Check your email (#{@user.email}) for your new password."
    redirect_to_back_or_default('/')
else
    flash[:error] = "Look at the errors below"
end
于 2009-04-08T23:22:59.443 回答
1

我同意莎拉·梅的观点。这是由于restful auth存储密码的方式。通常attr_accessor :password在用户模型中为密码设置一个虚拟属性,然后在您注册时使用该属性。在注册阶段,用户对象将密码属性设置为某个值,但是当您稍后去检索用户记录时,密码字段将为空白。

无论如何,我认为这不是“最好”的做事方式,向他们发送一个链接,他们可以在其中重置密码,而不仅仅是他们的原始密码,因为如果他们忘记了一次,是什么阻止他们再次忘记它?

于 2009-04-08T23:29:12.440 回答
1

不要这样做

许多用户在多个地方使用相同的密码(是的,不应该,但他们确实这样做了)。以纯文本形式存储他们的密码不仅会危及您网站的安全,还会危及您在其他网站上的用户的安全。甚至不要让我开始通过电子邮件以明文形式发送密码。

按照这里其他人的建议,有一个密码重置系统,而不是“这是你的密码”系统。

于 2009-04-09T00:05:40.183 回答
0

我猜密码是以散列形式存储的,故意让你知道用户的密码。当用户忘记密码时,您需要做的是向用户发送一个链接,该链接仅在几天内有效,这将使用户在不知道旧密码的情况下重置密码。

于 2009-04-08T23:14:26.237 回答
0

restful-authentication 仅临时存储密码- 足够长的时间来加密它并保存加密版本。正如其他人提到的那样,这是为了安全。

由于您不太担心这个应用程序的安全性,我建议为每个用户生成一个唯一的令牌,并为他们提供一个用于登录的 URL。因为“密码”(甚至是生成的)而推荐一个 URL 可能会让用户期望他们可以更改它。您可以向您的用户发送电子邮件,例如:

 Bryan,
  Your membership details:
  Username: bryan
  Your url: http://domain.com/x7sjs0qn

您的用户可以点击该 URL 并自动登录。这样一来,您就永远不会让用户有机会给您他们可能在其他地方使用的密码,并且 - 如果他们忘记了密码,您可以以纯文本的形式通过电子邮件发送,而不会使他们的其他帐户面临任何风险。

于 2009-04-10T18:12:43.407 回答