访问用户密码:Rails中的可变范围

时间:2009-04-08 22:59:27

标签: ruby-on-rails ruby variables scope restful-authentication

我正在为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没有通过。

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

6 个答案:

答案 0 :(得分:2)

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

虽然注册电子邮件在加密之前使用密码是可能的。未加密的密码通常不适用于以后的操作,因为它以加密方式存储在数据库中。

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

无论如何,这与人们在没有看到代码的情况下所能做的一样多。

答案 1 :(得分: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

答案 2 :(得分:1)

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

我不认为这是做事情的“最好”方式,给他们发送一个链接,他们可以重置密码而不是原来的密码,因为如果他们忘记了一次,是什么阻止他们再次忘记密码?

答案 3 :(得分:1)

不要这样做

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

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

restful-authentication stores the password only temporarily - 足够长时间加密并保存加密版本。这是为了安全,正如其他人提到的那样。

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

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

您的用户可以点击该网址并自动登录。这样,您永远不会让用户有机会为您提供他们可能在其他地方使用的密码,并且 - 如果他们忘记了密码,您可以通过纯文本发送电子邮件,而不会将其他帐户置于任何风险之中。