The navigator.id API

  • Revision slug: Mozilla/Persona/The_navigator.id_API
  • Revision title: The navigator.id API
  • Revision id: 478173
  • Created:
  • Creator: wbamberg
  • Is current revision? No
  • Comment

Revision Content

For full details about the navigator.id API, refer to its reference pages.

With Persona, a website asks the user to provide an "assertion", which is a digitally signed email address. By verifying the signature, the site can be assured that the user really does control the address in question. The site can then use this email address as an identifier for that user.

To ask for an assertion, the website calls a JavaScript API defined by the id object, which is a member of the global navigator object.

In future we expect the id object to be built into the browser, but at the moment it isn't, so sites using Persona need to include the polyfill library hosted at https://login.persona.org/include.js in their pages. After that, they can work as if id is just a built-in member of navigator.

There are two current versions of the API: the "Callback API", and the newer "Observer API".

The Callback API

The Callback API consists of a single function, get(). It takes two arguments:

  • a callback function that will be called back with a signed assertion if the user successfully authenticates to their Identity Provider
  • an options object that mostly customizes the dialog presented to users: allowing a website to link to its privacy policy, to set background color or include an icon, for example

You call get(), and in the callback you send the assertion to the server to verify the assertion. If verification succeeds, you can log the user in:

var signin = document.getElementById('sign-in');
signin.addEventListener("click", getAssertion, false);

// get an assertion
function getAssertion() {
  navigator.id.get(verifyAssertion, {backgroundColor: "#606B72", siteName: "My Example Site"});
}

// send the assertion to the server for verification
function verifyAssertion(assertion) {
  var xhr = new XMLHttpRequest();
  xhr.open("POST", "/verify", true);
  var param = "assertion="+assertion;
  xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  xhr.setRequestHeader("Content-length", param.length);
  xhr.setRequestHeader("Connection", "close");
  xhr.send(param);
  xhr.onload = handleVerificationResponse(xhr);
}

The Observer API

The Observer API consists of three functions: request(), watch(), and logout().

The main difference between this API and the Callback API is that the Callback API doesn't maintain any state: it doesn't have any idea which user is currently logged into Persona in general or any site in particular. Each website is responsible for its own session management.

By contrast the Observer API implements its own session management. You call request() to ask for a signed assertion, as you do using get() in the old API. But request() doesn't take a callback parameter: instead, you call another function watch(), with which you register callbacks called onlogin and onlogout. Persona calls these callbacks when a user logs in or out respectively.

Like the callback to get(), the onlogin callback gets a signed assertion for you to verify.

This makes

First-time sign-in experience

The first time a user signs in using Persona, they may need to create a Persona account. This will happen if they haven't used Persona before and if their email provider does not support Persona. In this case they will be invited to create an account using the fallback provider. After creating an account, if they use the Callback API, they will not be automatically redirected to the original website to finish signing in: they will have to navigate back to the original website.

Session Management

The Callback API doesn't provide any support for session management: this is something the website needs to provide.

Revision Source

<div class="note">
  For full details about the <code>navigator.id</code> API, refer to its <a href="/en-US/docs/Web/API/navigator.id">reference pages</a>.</div>
<p>With Persona, a website asks the user to provide an "assertion", which is a digitally signed email address. By verifying the signature, the site can be assured that the user really does control the address in question. The site can then use this email address as an identifier for that user.</p>
<p>To ask for an assertion, the website calls a JavaScript API defined by the <code>id</code> object, which is a member of the global <a href="/en-US/docs/Web/API/Navigator"><code>navigator</code></a> object.</p>
<p>In future we expect the <code>id</code> object to be built into the browser, but at the moment it isn't, so sites using Persona need to include the polyfill library hosted at <a class="external link-https" href="https://login.persona.org/include.js" title="https://login.persona.org/include.js">https://login.persona.org/include.js</a> in their pages. After that, they can work as if <code>id</code> is just a built-in member of <code>navigator</code>.</p>
<p>There are two current versions of the API: the "Callback API", and the newer "Observer API".</p>
<h2>The Callback API</h2>
<p>The <a href="/en-US/docs/Web/API/navigator.id#CallbackMethods">Callback API</a> consists of a single function, <a href="/en-US/docs/Web/API/navigator.id.get"><code>get()</code></a>. It takes two arguments:</p>
<ul>
  <li>a callback function that will be called back with a signed assertion if the user successfully authenticates to their Identity Provider</li>
  <li>an options object that mostly customizes the dialog presented to users: allowing a website to link to its privacy policy, to set background color or include an icon, for example</li>
</ul>
<p>You call <code>get()</code>, and in the callback you send the assertion to the server to <a href="/en-US/docs/Mozilla/Persona/Remote_Verification_API">verify the assertion</a>. If verification succeeds, you can log the user in:</p>
<pre class="brush: js">
var signin = document.getElementById('sign-in');
signin.addEventListener("click", getAssertion, false);

// get an assertion
function getAssertion() {
  navigator.id.get(verifyAssertion, {backgroundColor: "#606B72", siteName: "My Example Site"});
}

// send the assertion to the server for verification
function verifyAssertion(assertion) {
  var xhr = new XMLHttpRequest();
  xhr.open("POST", "/verify", true);
  var param = "assertion="+assertion;
  xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  xhr.setRequestHeader("Content-length", param.length);
  xhr.setRequestHeader("Connection", "close");
  xhr.send(param);
  xhr.onload = handleVerificationResponse(xhr);
}</pre>
<h2>The Observer API</h2>
<p>The <a href="/en-US/docs/Web/API/navigator.id#ObserverMethods">Observer API</a> consists of three functions: <a href="/en-US/docs/Web/API/navigator.id.request"><code>request()</code></a>, <a href="/en-US/docs/Web/API/navigator.id.request"><code>watch()</code></a>, and <a href="/en-US/docs/Web/API/navigator.id.request"><code>logout()</code></a>.</p>
<p>The main difference between this API and the Callback API is that the Callback API doesn't maintain any state: it doesn't have any idea which user is currently logged into Persona in general or any site in particular. Each website is responsible for its own session management.</p>
<p>By contrast the Observer API implements its own session management. You call <code>request()</code> to ask for a signed assertion, as you do using <code>get()</code> in the old API. But <code>request()</code> doesn't take a callback parameter: instead, you call another function <code>watch()</code>, with which you register callbacks called <code>onlogin</code> and <code>onlogout</code>. Persona calls these callbacks when a user logs in or out respectively.</p>
<p>Like the callback to <code>get()</code>, the <code>onlogin</code> callback gets a signed assertion for you to verify.</p>
<p>This makes</p>
<p>First-time sign-in experience</p>
<p>The first time a user signs in using Persona, they may need to create a Persona account. This will happen if they haven't used Persona before and if their email provider does not support Persona. In this case they will be invited to create an account using the <a href="/en-US/docs/Persona/Bootstrapping_Persona">fallback provider</a>. After creating an account, if they use the Callback API, they <em>will not</em> be automatically redirected to the original website to finish signing in: they will have to navigate back to the original website.</p>
<h4>Session Management</h4>
<p>The Callback API doesn't provide any support for session management: this is something the website needs to provide.</p>
Revert to this revision