subzerocloud / postgrest-starter-kit

Starter Kit and tooling for authoring REST API backends with PostgREST
MIT License
744 stars 71 forks source link

Forgot Password/Password Recovery #32

Open jekirl opened 6 years ago

jekirl commented 6 years ago

Hi All --

I don't know if this is something that would make sense to include in the project itself, but it would probably be nice to have a section in the Wiki on password recovery (among other account management features). A more fleshed out auth system that doesn't require Auth0 would probably help draw a lot of people to the project.

I have done a simple and likely mediocre implementation here. It creates a JWT token with a short expiry with a claim ensuring that the JWT can only be used to change the user's password a single time within the allotted duration. The JWT is then sent off the the RabbitMQ bridge and the user is expected to handle the actual emailing -- much like the welcoming new users section on the wiki.

If there is demand for it I would be happy to flesh it out more, but it would be great if someone already had a battle tested/good solution that they could share.

Thanks

ruslantalpa commented 6 years ago

@jekirl this would be a welcomed/useful addition. I've looked at your code and it's a good start. One thing i would suggest is to not tie in the reset password process to rabbitmq, meaning the function should not send a message, but add a row to a "reset password tokens" table and then have a trigger for it that sends the notification. This way, one could write a worker that sends emails using either rmq or by directly polling the table (in case one does not need the rabbitmq complexity).

jekirl commented 6 years ago

Thanks for getting back to me @ruslantalpa. I have some apprehensions about storing tokens in the DB because it would then also require some sort of cleanup process.

We could use a token table as is the standard in most password reset processes, however, I am not sure how to handle the auto cleaning of expired rows. I would rather not introduce a cron job as a dependency.

I suppose one possibility might be to have the change_password procedure delete all expired tokens (using an index on expiration date) prior to querying to see if the requested one exists? This seems wasteful but I would prefer it to having the reset process be coupled with either RabbitMQ or a cron job....Do you think this is a reasonable approach?

ruslantalpa commented 6 years ago

You can handle the cleanup process by attaching a trigger to the table on insert so each time a new token is inserted, all the old ones are deleted. This way the change_password function will be "clean"

jekirl commented 6 years ago

I like that. Will switch it to that and update issue.