>
> The one slight issue
> is that if the user picks the same password (or ever does so in the
> future) then the hash could become the same again,
>

I don't think that's true, at least using django.contrib.auth.  The salt is
re-generated whenever the password is changed, so the odds of the user
picking the same password and obtaining the same salt are fairly close to
zero. :)

Including last_login in the hash is certainly a fine idea, though.

  -- Scott

On Sat, Jun 28, 2008 at 7:29 AM, Luke Plant <[EMAIL PROTECTED]> wrote:

>
> On Saturday 28 June 2008 01:39:26 Scott Moonen wrote:
>
> > > The problem with this is it requires state on the server, which
> > > means . . .
> >
> > I don't think it's necessary to implement this in such a way that
> > additional server state is stored.  Instead, you could let the
> > confirmation token be a hash of the internal user state --
> > including, most importantly, the user password's salt and encrypted
> > values.  That way, the valid confirmation token is 1) known only to
> > the server (the User 'password' field is not externalized), 2) able
> > to be computed at any time without being stashed anywhere, 3)
> > constant until the user changes their password, and 4) guaranteed
> > to change whenever the password is actually changed.
>
> When I was writing the email, I almost included something about
> including a 'last modified' timestamp on the user object, so I was
> getting close, but not quite.  This is great.  The one slight issue
> is that if the user picks the same password (or ever does so in the
> future) then the hash could become the same again, and anyone who
> intercepted the email once would be able to reset the password again.
> However, this is fixable by including user.last_login in the hash of
> the internal user state. (We don't want to force people to use
> different passwords, and we can't do that properly anyway without
> keeping a history of password hashes).
>
> So, the URL would end up like:
>
> https://example.com/reset/34-7127f83ebf8ce7ed22bdc50a50572a30
>
> i.e.
>
> https://example.com/reset/{uid}-{hash}<https://example.com/reset/%7Buid%7D-%7Bhash%7D>
>
> where
>
> hash = sha1(settings.SECRET_KEY + str(user.id) + user.password +
>            str(user.last_login))
>
> The reset page then allows the user to enter a new password.  It sets
> the new password (which *is* allowed to be the same as the last
> password) and updates the last_login timestamp.
>
> I'm happy to implement -- I've got the tests setup already etc, so it
> should be easy enough.
>
> Luke
>
> --
> "I have had a perfectly lovely evening. However, this wasn't it."
> (Groucho Marx)
>
> Luke Plant || http://lukeplant.me.uk/
>
> >
>


-- 
http://scott.andstuff.org/ | http://truthadorned.org/

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to