Goldilocks: Declarative HTML API?

183 views
Skip to first unread message

Sean McArthur

unread,
Nov 12, 2013, 10:29:30 PM11/12/13
to dev-id...@lists.mozilla.org
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

Dirkjan Ochtman

unread,
Nov 13, 2013, 4:15:24 PM11/13/13
to Sean McArthur, dev-id...@lists.mozilla.org
On Wed, Nov 13, 2013 at 4:29 AM, Sean McArthur <smca...@mozilla.com> wrote:
> tl;dr - See title. See some code[1]. Now keep reading, so you can comment.

I think it's awesome. This is exactly how login for the web should work.

Nit: claiming rel="login" for Persona/BrowserID seems a little bold.
Maybe rel="persona-login"?

Cheers,

Dirkjan

Andrew Chilton

unread,
Nov 13, 2013, 5:20:46 PM11/13/13
to dev-id...@lists.mozilla.org
On 14/11/13 10:15, Dirkjan Ochtman wrote:
> On Wed, Nov 13, 2013 at 4:29 AM, Sean McArthur <smca...@mozilla.com> wrote:
>> tl;dr - See title. See some code[1]. Now keep reading, so you can comment.
>
> I think it's awesome. This is exactly how login for the web should work.

I agree, this is awesome work. I love the declarative nature.

One of the things I did earlier in the year was the Persona Assistant
plugin for jQuery. Essentially I wanted to abstract out much of the
JavaScript side and just gather various bits of info from the page itself.

e.g. I used any ".persona-login" element to activate login, like your
a[rel="login"].

If this all happens, Persona Assistant can be ditched and that'll be
fantastic (not because I don't like it, but because it'd be unnecessary).

One question. Would the RP be able hook into any browser events so that
we can change the page slightly? For example, when someone clicks the
login button. Or if they canceled the login process.

Cheers,
Andy

Dan Callahan

unread,
Nov 19, 2013, 10:26:38 AM11/19/13
to dev-id...@lists.mozilla.org
This is awesome! Comments on the specific proposal below.

(TL;DR: I'm +1 on exploring the idea, -1 on doing that in core.)

Where do we go from here? This feels like a nontrivial amount of new,
exploratory design at a point when we're trying to reduce our surface
area and stabilize the API.

Can this work merge with Andy's Persona Assistant, instead of going into
mainline Persona? That feels reasonable since we'd have to provide a
shim regardless, right? Once it's matured there we could consider
rolling it into the spec for BrowserID 2.0...

On 11/12/13 9:29 PM, Sean McArthur wrote:
> 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.
>
> [...]
>
> 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>

As per #1 above, or in the presence of multiple login buttons, wouldn't
this need to live in some sort of meta tag?

Another benefit: a declarative API based on HTTP POSTs clears the way
for better console/scripted interaction with Persona.

> This means Persona works without JavaScript!

Provided you have native support in your browser -- or an extension
installed. :) Though this *does* provide a more graceful fallback for
people with JS disabled...

> Mobile apps could exclude the include.js entirely, which would save users
> bandwidth.

Isn't this already true of the current APIs, once we have a stable spec?

-Callahad

Francois Marier

unread,
Nov 19, 2013, 10:56:48 AM11/19/13
to
On 19/11/13 07:26, Dan Callahan wrote:
> (TL;DR: I'm +1 on exploring the idea, -1 on doing that in core.)

I also think it's a brilliant idea. I've been meaning to explore this
for ages so kudos on Sean for resurrecting the idea and bringing code to
the table.

Short term, I'd suggest the same thing as Dan: keeping that exploration
outside of core so that we can finalize v1.0 of Persona/BrowserID. This
declarative stuff could form the basis for the next version though, it's
very neat and I'd love to play with it on some test RPs.

>> This means Persona works without JavaScript!
>
> Provided you have native support in your browser -- or an extension
> installed. :) Though this *does* provide a more graceful fallback for
> people with JS disabled...

Personally, I think that if we're going to propose a solution that works
without JavaScript, it's totally fine to require native support or an
extension. Those who care have already installed NoScript or have some
other need that requires extra software.

Francois

Benjamin Smedberg

unread,
Nov 19, 2013, 11:27:39 AM11/19/13
to Francois Marier, dev-id...@lists.mozilla.org
On 11/19/2013 10:56 AM, Francois Marier wrote:
> On 19/11/13 07:26, Dan Callahan wrote:
>> (TL;DR: I'm +1 on exploring the idea, -1 on doing that in core.)
> I also think it's a brilliant idea. I've been meaning to explore this
> for ages so kudos on Sean for resurrecting the idea and bringing code to
> the table.
I explored this a while back, and it wasn't really possible then because
of the login/logout session tracking which requires JS callbacks to be
useful. I'm happy that we've ditched all that.

At the time, my system used <input type="identity"> and the assertion
was simply submitted as a part of the <form> to the server. You can
polyfill this using a JS shim into a login button.

--BDS

Sean McArthur

unread,
Nov 21, 2013, 12:06:46 AM11/21/13
to Dan Callahan, dev-id...@lists.mozilla.org
On Nov 19, 2013 7:27 AM, "Dan Callahan" <dcal...@mozilla.com> wrote:
>
> Where do we go from here? This feels like a nontrivial amount of new,
exploratory design at a point when we're trying to reduce our surface area
and stabilize the API.
>
> Can this work merge with Andy's Persona Assistant, instead of going into
mainline Persona? That feels reasonable since we'd have to provide a shim
regardless, right? Once it's matured there we could consider rolling it
into the spec for BrowserID 2.0...

I know it seems like the opposite of what we are supposed to do this
quarter, but I think it could be justified. The more I think about it, the
more convinced I am that an HTML part of the spec should be required for
1.0.

Also, Goldilocks isn't complete yet. What's currently in dev still does not
completely work without cookies. This continues to alienate Safari and
"private browsing" modes. We *need* some way of passing the assertion back
to the website without using an iframe.

>
> As per #1 above, or in the presence of multiple login buttons, wouldn't
this need to live in some sort of meta tag?

With only one button, a native implementation can see what is declared in
the element. Multiple buttons could perhaps include different options
declared? Or, we could permit a <link> element to be meta?

>
> Another benefit: a declarative API based on HTTP POSTs clears the way for
better console/scripted interaction with Persona.

I tried to think of a way that allowed Persona to post back to native apps,
but I don't see how. POST is an httpverb, and I don't know if it's
standardized how browsers would handle a POST foo://auth/verify. It is a
step closer to getting there, however.

>> This means Persona works without JavaScript!
>
>
> Provided you have native support in your browser -- or an extension
installed. :) Though this *does* provide a more graceful fallback for
people with JS disabled...

Or, as was suggested, it allows users to whitelist Persona, and not have to
whitelist every page they wish to log in to.

>
>> Mobile apps could exclude the include.js entirely, which would save users
>> bandwidth.
>
>
> Isn't this already true of the current APIs, once we have a stable spec?

No. For a mobile app to use Persona now, they would need to include the
shim. To work on all mobile browsers. With the declarative HTML, they could
not include any shim, since redirects and post backs will work in any
browser. And then FxOS would make it nicer.

Sean McArthur

unread,
Nov 21, 2013, 12:17:02 AM11/21/13
to Dan Callahan, dev-id...@lists.mozilla.org

Sean McArthur

unread,
Nov 21, 2013, 10:36:58 AM11/21/13
to Dan Callahan, dev-id...@lists.mozilla.org
(dan. excuse the dupes. android doesn't like me using multiple accounts it
seems)

Sean McArthur

unread,
Dec 2, 2013, 2:04:30 PM12/2/13
to dev-id...@lists.mozilla.org, Dan Callahan
Any further thoughts of the points I brought up?
Reply all
Reply to author
Forward
0 new messages