Programming with Gotos
OK, I’ve not got an OpenID server on Rails, and seem to be over the hump understanding OpenID.
Inhibitors:
- By necessity, OpenID only documents half of a protocol. How you do logins needs to be an integral part of the solution, but by design, this is something that every implementation can vary.
- The OpenID protocol is essentially one of programming with GOTOs. Reminds me of SNOBOL. Several actions end up having a fail_to and sucess_to parameters, which determine the next resource.
- Several actions have a number of alternatives. The choice between the alternatives requires a deeper understanding of the tradeoffs, which doesn’t happen until you understand one complete path.
- The Python implementation is too abstract for me to follow. Server calls a library method which calls another library method which raises an exception which is caught and then forwarded to a method that is not implemented - oh, but wait, it is subclassed, by a method that does a redirect. Not to be confused with another method that has essentially the same name and function, but does a completely different redirect.
As I said before, constructing test cases helps me. Here’s what I found:
Normal flow (stateless consumer):
A form is presented. POSTing your identity URL to it causes the consumer to fetch that page, find the server, and return a redirect to that server, along with a “return_to” URI as a query parameter. In the “steady state” case, that server simply returns a redirect back to the consumer, adding tokens, again as query parameters. To close the loop, the consumer then directly contacts the server, and asks “did you provide these tokens?”
Normal flow (stateful consumer):
A form is presented. POSTing your identity URL to it causes the consumer to fetch that page, find the server, and return a redirect to that server, along with a “return_to” URI as a query parameter. In the “steady state” case, that server simply returns a redirect back to the consumer, adding tokens, again as query parameters. As the consumer had previously established a shared secret, it can verify those tokens for itself.
A few variations make this even more interesting. Once the browser has been redirected to the server, the server has access to server specific cookies, and can present whatever forms it likes. All it has to do is ensure that it propagates (or retains) the “return_to” URI. The consumer also has an interface which requests that this not be done, and for control to return back immediately, even in the case of failure.
As I said, I am doing this as a learning exercise. I suspect that others may learn from what I did. Meanwhile, the folks at Janrain are busy building a library that others may want to actually deploy.