Your password reset link should lead to a page where you have a button that he pushes to submit a POST to reset his password. Otherwise a user's password could be reset without his knowledge.
It comes from an e-mail sent to the address associated with the account, though. The only way he can get the reset code is to have it e-mailed to him, so unless he's forwarded on the e-mail to someone else (why would you do this?), the reset is coming from him.
I wouldn't put up a GET page where anyone could reset anyone else's password - that would be silly. (Though fun in a chaotic way...)
Edit: To clarify, the workflow goes like this:
1) Unauthenticated user visits forgot_password, enters in either username or e-mail address, submits a POST back to system with those parameters.
2) POST handler generates a unique reset code and embeds it into an e-mail that's send to the e-mail address associated with the account.
3) User clicks on a link in that e-mail and visits a GET page that resets the password to a random one and tells the user what it is. Also logs the user in.
4) There is a link on that page that lets the user change it instantly, so they don't have to use the randomly-generated password permanently.
A simple POST to reset the password doesn't work, because a "forgot password" link necessarily requires that the user not be authenticated (otherwise, they haven't forgotten their password ;-)). So you need the extra e-mail verification step so people can't change other people's passwords.
Say Joe User has an account at your site, and Arnie Asshole knows Joe's email address, and he knows that Joe uses a web accelerator. So he goes to your site and puts in Joe's email address. Joe goes to look at the resulting email he gets in his webmail, and bam, his password has been reset without his knowledge, because his web accelerator followed the link in the email.
The workflow should be like this:
1) as in your example
2) as in your example
3) User clicks on a link in that email and visits a GET page. The GET page has a form with a single button ("Really Reset My Password" or something), or maybe it has a form right there for him to enter his new password.
4) He clicks the submit button, and the form submits right back to that same url, with the reset code embedded in the url, but this time it's a POST.
5) Your site's code detects it's a POST this time, and changes the password.
I was never suggesting you bypass the email verification step. Just add an extra screen between clicking the link in the email, and the password actually being reset.
> It comes from an e-mail sent to the address associated with the account, though. The only way he can get the reset code is to have it e-mailed to him, so unless he's forwarded on the e-mail to someone else (why would you do this?), the reset is coming from him.
So what happens when your fancy new spam filter follows the link in your email to see how spammy the page is? You end up locked out of your account, logged out, with a random password you can't retrieve.
It's really not hard to come up with scenarios where GETs are automatically performed. The HTTP 1.1 specification was written with this in mind. Assuming that it's not going to happen is simply an unnecessary risk.