tl;dr - See title. See some code[1]. Now keep reading, so you can comment.
We're getting out of the state management business. We've done part of that
with current Goldilocks work, but it's not completed. We still have a few
loose ends:
1. To support native Persona buttons in browser chrome, all options to
request() need to be moved to watch(), so the browser can know them.
2. We still don't work for users that have to do email verification in
Safari, since once they come back from closing a tab, we'll still be 3rd
party.
Since everything needs to be declared in watch() anyway, it seems like a
small skip to support an fully HTML declarative API, as suggested in this
issue[2] by @eevee.
## How
There becomes potentially 3 ways to integrate with Persona this way.
1. HTML only
2. HTML + shim only
3. JavaScript like normal
### HTML only
An RP can express Persona support in HTML by including an anchor tag with a
rel="login" attribute. Additional options can be included as data-*
attributes. The href is considered the returnTo (and postBack, we'll come
back to that). Example:
<a href="/auth/verify" rel="login" data-siteLogo="/i/logo.png"
data-siteName="123done">Login</a>
This will also require a bit of server-side scripting to make it work.
Specifically, if a user clicks the link, a GET to the href would do a
redirect to
login.persona.org/sign_in#origin=123done.org&returnTo=/auth/verify&siteName=123done
The dialog would handle the request as normal, and upon completion of
authentication, we would POST the assertion to the returnTo address. This
means the RP would need to also handle a POST to /auth/verify (in this
case) to accept an assertion and verify it, and then redirect to wherever
else they want on their site.
The POST part shouldn't actually be more work for them, since they already
would need an endpoint to verify the assertion. However, whereas normally
the POST would come from their own AJAX, they could protect their endpoint
from CSRF. To stay protected, they'd need to pass a csrf token in the
returnTo if redirecting from their auth URL to our dialog, and we'd simply
POST it back without doing anything, since we would POST to their returnTo.
If the browser natively supports Persona, it can look for these kinds of
anchors, and attach to them. Even without JavaScript enabled, the browser
can still do whatever it wants, and can open a door hanger or trusted UI,
do Persona, and then automatically POST to the href.
#### Benefits
This means Persona works without JavaScript! Well, sort of. But, again as
@eevee pointed out, the redirect would take place, and then Persona's page
could rightfully show a noscript message. Users could easily whitelist
Persona, without whitelisting each site individually.
Mobile apps could exclude the include.js entirely, which would save users
bandwidth.
The communication_iframe is no longer needed in this instance! Performance
win! Also means we aren't rely on any 3rd party mechanism, so we'll work in
Safari / 3rd-party-cookies-disabled.
### HTML + shim only
Including all of the above, the RP could optionally include the shim, and
use it with the declarative HTML. If there's no JavaScript, it works as
above. If there is, the shim would look for `a[rel=login]`, and if found,
automatically setup watch() and request() upon click. This would give the
user a slightly better experience, as they use a popup and don't lose
context of the main window. We would use the onlogin callback of watch() to
then POST to the href of the anchor.
### JavaScript like normal
If people don't want to use the HTML, they can continue to interact with
navigator.id using JavaScript. We would still recommend that all properties
be put into watch() instead of request(), and my Pull Request[1] outputs
deprecated warnings for all options passed to request().
We may want to recommend setting up the GET and POST endpoints on their
returnTo anyway, to support both no JavaScript, and returning users from
email verification who closed the original tab.
## Code
I put my work-in-progress into a Pull Request, so that others can try it
out, and whatever. Fiddle. Comment. Complain. As you do. [1]
[1]:
https://github.com/mozilla/browserid/pull/4021
[2]:
https://github.com/mozilla/browserid/issues/1946#issuecomment-23242039