what is the best way to generate a reset token in python?

Abdelouahab Pp picture Abdelouahab Pp · Feb 5, 2013 · Viewed 11k times · Source

I'm trying to make a validation process for a password reset, what i've used are two values: the epoch time, and i want to use the users's old password (pbkdf2) as a key,

Since i dont want to get non ASCII characters, i've used SimpleEncode library because it's fast since it's only a BASE64 with a key used, but the problem is that the password is too long (196 chars) so i get a long key!

What i've done is split the result code = simpleencode.encode(key,asci)[::30], but this will not be unique!

To get an idea how it works, i've tried Facebook reset process, but what is given is a number! so how this process works, don't they use a key to make it hard for someone to forge a link to reset someone's password?

Update: how the algorithme will work:

1- get the time using epoche time.time()

2- generate the Base64 of the epoche time (to use for the URL) and the epoch time value + a key, this key is PBKDF2(password).

3- generate the url www.example.com/reset/user/Base64(time.time()) and send this URL + the simpleencode.encode(key,asci)[::30]

4- when the user clicks on the URL, he put the generated code, this generated code, if it matches with the URL, then let him modifiy the password, else, it is a forget URL!

Answer

Jon Clements picture Jon Clements · Feb 5, 2013

Not sure it's the best way, but I'd probably just generate a UUID4, which can be used in a URL to reset the password and expire it after 'n' amount of time.

>>> import uuid
>>> uuid.uuid4().hex
'8c05904f0051419283d1024fc5ce1a59'

You could use something like http://redis.io to hold that key, with a value of the appropriate user ID and set its time to live. So, when something comes in from http://example.com/password-reset/8c05904f0051419283d1024fc5ce1a59 it looks to see if it's valid and if so then allows changes to set a new password.

If you did want a "validation pin", then store along with the token, a small random key, eg:

>>> from string import digits
>>> from random import choice
>>> ''.join(choice(digits) for i in xrange(4))
'2545'

And request that be entered on the reset link.