views:

43

answers:

4

Generally, a get request is not meant to have any side-effects. However many sites allow you to reset your password or authenticate your email/user by clicking a link embedded in the email. Since we don't want to send HTML emails and therefore cannot use a form in which the data is POSTed, we have to use a get request. However it is considered bad design to have Requests using GET with side-effects. What is your opinion about this? Is there any way to solve this dilemma?

A: 

Yes, to link to a page that has no side-effects that can POST to perform the reset.

spender
+3  A: 

Normally such links only contain a token that identifies the user who wants to reset the password resp. the request to reset the password. It does not log in the user.

Then a form is shown where the user can create a new password.

Anyway, that a GET request should be idempotent is not a hard fact, it is more a guideline. If it improves the usability for the user not to stick to that guideline than go for it (after considering alternatives and consequences of course). In the end, usability matters.

But if you want to reset the password by generating a random password and send it to the user, don't do it. Sending plaintext passwords in unencrypted emails is a very bad idea. In this case I would prefer security before usability and let the user choose it by himself.

Update

Btw. a very important point with such URLs is that they normally are only accessible once or at least only as long as the user has not finished the procedure. So although you might change something with the GET request, the resource will be deleted anyways.

Felix Kling
A: 

GET must be idempotent - getting the same resource should give the same value, and it should be safe. Safety implies that the user is not held responsible for any side-effect.

Although idempotency and safety generally imply absence of side-effects, I would consider acknowledging the receipt of an email or resetting a password to be both idempotent and safe - acknowledging or asking for a form to reset more than once does not alter the resource (assuming the response to resetting the password is to show a form which is POSTed to enter a new password).

If a user had a mail agent which retrieved and cached all URLs in messages, then the effect that the user would have inadvertently triggered would be to have acknowledged receipt of the email (which is harmless, and 'true'), or inadvertently retrieved a form to reset his password. If the reset link actually resets the password on the GET rather than on the form's POST, then it's a bit more grey, but more of a usability issue than anything else - if the reset token is only good for a given number of hits, then it can't constitute a denial of service.

Pete Kirkham
+1  A: 

This is an interesting usage, and I believe it's an acceptable practice. But this isn't an exception to the rule. Basically, the way this is usually implemented, you have to initiate the password reset beforehand in a different way, usually by entering your username or email into a POST form.

You can think of that POST request as essentially the operation that resets your password. But even though you've begun the process of resetting the password, the system still needs to verify your identity. This is usually done by sending an SMS message or email with a code/security token that is linked to that POST request. All the process needs to be completed is for the system to receive that code from you any way possible. You can either type it into another POST form (e.g. if you receive it by SMS), or it could be embedded into an e-mail link.

So even though, technically speaking, your final GET request has a side-effect, it's still an idempotent operation. Because that link, on its own, does not do anything unless you already made the earlier POST request to start the reset process. And any subsequent requests to that GET url will have no effect.

Edit:

I think it should also be noted that putting the link in an e-mail circumvents the problem of webcrawlers accidentally triggering your non-idempotent operations. In addition, the fact that most such links immediately redirect to a side-effect-free page, and the fact that the page itself has a single-use token, means that the back and refresh buttons can't cause any unwanted side-effects either.

Lèse majesté