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

发布于 2024-07-17 14:51:18 字数 868 浏览 6 评论 0原文

我正在为 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 无法通过。

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

I'm writing a very simple mailing system for a Rails app. I'm using RESTful authentication.
It's a fairly conventional setup, where I'm sending the same email when a user signs up and when a user forgets their password.
I'm just having one problem that I can't seem to wrap my head around.

I'd like to use the same email template for both instances, even though the "new user" email will come from a users controller and the "forgot password" email will come from a passwords controller.

The email looks something like this:

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

When a user signs up, this works just fine, causing an email that looks something like:

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

Unfortunately, everything breaks when attempting to use this template to send a "forgot password" email from the passwords controller.
The thing that's perplexing me, though, is that it only sort of breaks:

  Bryan,
  Your membership details:
  Username: bryan
  Password: 

In other words, @user.name is still valid, as is @user.login. But for some reason in this state @user.password doesn't come through.

Thanks for the responses. To be clear, security really isn't an issue in this case, and for that reason it'd be nicer to be able to send a forgotten password in plain text rather than going through the resetting password process, but I do appreciate that this is usually not the case.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

执手闯天涯 2024-07-24 14:51:18

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

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

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

不管怎样,这就是人们在没有看到代码的情况下所能做的尽可能多的猜测。

It's hard to say without seeing some of your code, specifically the controller methods.

It's possible though that the signup email is using the password before it's encrypted. The unencrypted password generally isn't available to later actions, because it's stored encrypted in the db.

If however your password controller is setting a new password, rather than trying to retrieve the old one, then the problem is most likely elsewhere.

Anyways, that's about as much speculation as one can do without seeing code.

怼怹恏 2024-07-24 14:51:18

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

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

I agree with Sarah Mei. It's due to restful auth's way that it stores passwords. Generally attr_accessor :password in the user model sets up a virtual attribute for the password which is then used when you go to sign up. During the signup phase the user object will have the password attribute set to something but when you go to retrieve the user record later on the password field will be blank.

I don't think that's the "best" way of doing things anyway, send them a link where they can reset their password rather than just their original password because if they forgot it once, what's stopping them from forgetting it again?

余生再见 2024-07-24 14:51:18

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

在将明文密码存储到数据库之前,您必须将明文密码存储在另一个变量中,使用带有明文密码的单独变量,您可以将其传递给 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

If you look in the database you will see a password hash and a salt hash.

You would have to store the plaintext password in another variable before storing it into the database, using the separate variable with the plaintext password you can pass that to the ActiveMailer and send it without the encryption in the email.

@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
最笨的告白 2024-07-24 14:51:18

不要这样做

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

按照其他人的建议,使用密码重置系统,而不是“这是您的密码”系统。

Don't do this

Many users use the same passwords in multiple places (yeah, the shouldn't, but they do). Storing their passwords in plain text risks not only the security of your site, but also the security of your users on other sites. And don't even get me started on sending passwords in clear text via e-mail.

Do as the other's here are suggesting, have a password reset system, not a "here's your password" system.

木有鱼丸 2024-07-24 14:51:18

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

I'm guessing that the password is stored in a hashed form, deliberately so that you can't know the user's password. What you need to do when a user forgets a password is to send the user a link, only valid for a few days, that will let the user reset the password without knowing the old one.

夜清冷一曲。 2024-07-24 14:51:18

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

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

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

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

restful-authentication stores the password only temporarily - just long enough to encrypt it and save the encrypted version. That's for security as others have mentioned.

Since you're not too worried about security for this app, I'd recommend generating a unique token for each user and supplying them with a URL to use for login. Recommending a URL because 'password' (even generated) might give the user the expectation that they can change it. You could email your users something like:

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

Your users could hit that URL and login automatically. That way you never give the user a chance to give you a password they might use elsewhere, and - if they forget it, you can email it in plain text and not put their other accounts at any risk.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文