Explanation of the token-based password-reset functionality in Flask-Security
Asked Answered
O

1

6

Can someone walk me through what's happening in flask-security's password reset token? The code is here on github:

https://github.com/mattupstate/flask-security/blob/develop/flask_security/recoverable.py

(There may be other parts up a directory.)

My understanding of what's happening:

  1. In the route defined by forgot_password() user submits a form to reset password
  2. A "reset_password_token" is generated. This consists of the user's ID + an md5() of the user's current (stored-encrypted) password?
  3. A link is generated to a reset password address containing the token.
  4. This link is emailed to the address given by user.email
  5. When the user clicks that link, they go to a route (defined in views), which is reset_password(token). The token value is an argument to this route.
  6. The route evaluates whether the token is valid and not expired.
  7. If so, this route renders a form asking for a new password, ResetPasswordForm().

Is that correct?

Also:

  1. If above is correct, is it safe to make the token contain a new md5() of the current password? I know it should be unique and costly to reverse, but still?
  2. Where is the expiration date stored?

I'm most specifically confused by the generate_password_reset function

data = [str(user.id), md5(user.password)] return _security.reset_serializer.dumps(data)

and the

get_token_status(token, 'reset', 'RESET_PASSWORD') function inside reset_password_token_status(token)

Oraleeoralia answered 16/12, 2012 at 23:23 Comment(0)
A
5

It is using the itsdangerous module to serialize the token. If you read more about it below, you will have your answers on how expiration timestamp is used etc.

http://packages.python.org/itsdangerous/

The function serializer.dumps() creates a unique serialized string and serializer.loads() which is called by get_token_status will return exceptions unless the exact serialized value is provided to it as parameter.

So you dumps() and then using the return value from that, you calls loads(). If does not match, you have exception which in this case means bad token.

Anthropomorphous answered 17/12, 2012 at 18:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.