I had dinner with Bill Venners in Santa Clara last night. A lot of the action at the recently concluded Software Development 2006 conference focused on REST, so that was very much on our minds. We’ve both spent a lot of time working on server side frameworks for publishing systems, he at Artima, me here at The Cafes and its sister sites. Gradually the conversation wandered into authentication systems.
Among other topics, I described to Bill the cookieless, registration free authentication I had designed for version 1.0 of this site. I’m no longer using that system since switching to WordPress for other reasons, but I’m still quite proud of it; and I’m not sure it’s been duplicated anywhere else. However Bill immediately noticed one fatal (but correctable) flaw in my approach.
The way the system worked you had the option to register with a user name and password. If you did so you could comment with your user name and password and the comment would be immediately posted. That’s not especially unique. Many blog and BBS systems work exactly like that. What was different was that you could also post without registering and still be authenticated. If you did not supply a user name and password, then the system would e-mail you a confirmation URL. The comment would not be posted until you clicked on the URL. At that point you’d see a screen like this one, and the comment would be published:
This more or less completely eliminated spam and forged comments but was really easy for users.
The problem Bill noted was that this design isn’t RESTful. In particular I was using a GET to make something happen: confirm a message. What really shocked me was that Google’s GMail and possibly other clients will prefetch such URLs, maybe even before the user ever reads the e-mail. In other words, the confirmation can be accidental. Oops. As soon as Bill pointed it out, I saw my error. Google is absolutely within its rights to prefetch such a URL. I should not be using a GET to confirm the message. That needs to be done with a POST.
As Bill reminded me, the correct solution is to have the URL in the e-mail message go to a form page like this one:
The user would need to take an extra step of actually clicking on the button, which would submit the form and confirm the comment via POST, not GET. This is the correct RESTful design for this system, though it is a two-click process rather than a one-click process. From a user interface perspective, I don’t like the extra click, but it is absolutely necessary for the proper functioning of the Web.
I’m not the only one to make this mistake though. Many mailing lists use something a lot like this scheme to confirm subscriptions, and they have the exact same problems. They need to be fixed. Embarassingly the rest-discuss mailing list itself has this very problem. In fact, it has both problems. To confirm a subscription you GET a URL sent in an email message and then you GET a second URL you find on that page. In other words it’s a two-click process, but both clicks use GET, and are cacheable, spiderable, and prefetchable but not side-effect free. (In fairness, this is not just rest-discuss. All mailing lists hosted on yahoogroups have this problem. Still you’d think the RESTafarians could find a REST friendly e-mail host. For instance, the listproc software IBiblio uses to host xom-interest and other mailing lists gets this absolutely right.)
There is a RESTful solution though. Instead of sending plain text containing a URL, I could send an HTML e-mail containing a form that uses POST to submit the confirmation. That would be fully RESTful, and not require more than one click. The downside is that it requires an HTML-capable e-mail client. Most of my target audience (including me) prefers plain text e-mail so this is probably worse than the two-click solution.
(Oh, and for anyone who’s keeping score, on rereading the code I wrote two years ago, I discovered that The Cafes did actually get this right the first time. I just misremembered how my system worked when I described it to Bill over dinner last night. However the issues about mailing list confirmations and one-click vs. two-clicks are still very real.)