AccountChooser Working Group T. Bray
Internet-Draft Google Inc.
Expires: October 3, 2015 N. Sakimura
Nomura Research Institute
P. Dingle
Ping Identity
D. Salama
Google Inc.
April 2015

OpenID AccountChooser Advanced Specification
draft-accountchooser-advanced-01

Abstract

AccountChooser is a facility where users can store basic identifying information for accounts that they use for signing in to Web sites (Sites). Once stored, users are able to use the AccountChooser user interface to transmit identifying information to sites rather than typing that information into login or signup forms manually.

This specification standardizes a low-level JavaScript interface that can be offered by an AccountChooser, enabling developers to leverage AccountChooser functionality for login and signup pages, and push new Account Records into the Chooser, through javascript methods exposed by the AccountChooser API. This developer wishing to build their own AccountChooser can do so by meeting this specification.

For Site owners wishing to integrate quickly with a higher-level interface, see the OpenID AccountChooser Web Integration 1.0 document.

Status of This Memo

This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at http://datatracker.ietf.org/drafts/current/.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

This Internet-Draft will expire on October 3, 2015.

Copyright Notice

Copyright (c) 2015 IETF Trust and the persons identified as the document authors. All rights reserved.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.

1. Introduction

The most common representation of a relationship between a user and a web site today is a “primary account”. A primary account at a site is a stand-alone collection of attributes and settings, organized around an identifier such as an email address, and protected by a locally stored credential, most often a password. Users end up typing the same information over and over again, during signup and login activities, and can feel challenged to recall which set of identity information has been supplied to which site.

In addition to primary account management, sites may optionally offer federated account options, where the site does not store a credential for the account directly, but instead relies on another service (such as a social network or corporate federation service) to validate the identity of the user. In this case, a user returning to a site may not only need to remember which username they used with a site, but also which federated identity provider they linked to the site.

From the perspective of a user, an AccountChooser is a place where the user can store records of their different accounts, and reuse those records easily across multiple sites. The visual nature of an AccountChooser provides additional cues to remember which identities are stored where, and the act of “choosing” rather than typing means that login and sign-up are faster and less error-prone. The AccountChooser can be queried by sites, and while the user sees all the account records they might want to pass back to the site for the purposes of login or sign-up, the site only receives the identity information that the user chooses.

From the perspective of a site, the chooser is a way to help users remember their login information, thus reducing the likelihood of account abandonment and decreasing drop-off that may occur during login and signup. By using the AccountChooser Javascript interface, the site is able to populate login and signup pages with Account Record information received from the AccountChooser rather than directly from the user.

This document standardizes a design pattern for behavior of an AccountChooser and for a javascript-specific interaction between a Site and an Account Chooser. A conformant AccountChooser exists today at https://accountchooser.com. All examples derive from this reference implementation.

1.1. Requirements notation

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC2119.

2. Terms

For the purpose of this specification, the following terms are defined.

2.1. Account

A general collection of attributes about a user stored by a site.

2.2. Primary Account

An account that is validated directly at the site, for example by prompting the user for a password.

2.3. Federated Account

An account that is not validated directly at the site, but instead validated by an external entity such as a social network or a corporate IAM system, using identity standards.

2.4. Site

A website or other service at which users have accounts. Accounts may be primary accounts or federated accounts.

2.5. AccountChooser (AC)

A mechanism to remember and present to a user their list of Account Records. Sites interact with the Account Chooser to either request that the user be prompted to select an Account Record to be returned to the Site, or to add a new record to the Account Chooser.

2.6. AccountChooser Storage

A persistent database maintained by the AccountChooser, containing zero or more Account Records.

2.7. AccountChooser JavaScript (ac.js)

Javascript file invoked by the Account Holder that performs AccountChooser tasks.

2.8. User Claimed Identifier

The account record attribute that uniquely identifies the user. This specification uses the “email” field as the User Claimed Identifier.

2.9. Display Name

A human-readable name for the person associated with the user claimed identifier.

2.10. Provider ID

A URL identifying the service capable of validating the account referenced in the account record. In the case where the service specified by the Provider ID is not the Account Holder service, the Account Holder will likely make a federated call to the service indicated in order to validate the account, rather than locally validating the account.

3. Account Records

An account record is a collection of attributes that are passed between Sites and Account Choosers during invocation of the AccounChooser JavaScript. Examples of account record operations include requesting an account record to be chosen, checking the status of a chosen account record against an existing account at a site, or requesting that a new account record be stored. The AccountChooser negotiates with the user to complete those requests.

3.1. Account Record Object

An Account Record is represented by up to four pieces of information. The AccountChooser accepts/returns account(s) from/to other Sites. The Account Record is represented by a plain javascript object, which can have the below fields:

name type default value description
email string N/A Email address and user claimed identifier.
displayName string N/A Display name.
photoUrl string N/A A uri from which a photo a photo representing the user can be fetched
providerId string N/A Domain name identifying a federated Identity Provider.

4. AccountChooser JavaScript File

The method by which a site interacts with AccountChooser is a JavaScript file named ac.js, which performs a variety of tasks depending on where it is called from, and can be customized with configuration arguments.

The ac.js file may either be hosted with the site domain, or referenced remotely from the AccountChooser domain. This guide uses the default convention of a remotely referenced file from https://accountchooser.com/ac.js.

4.1. AccountChooser JavaScript Variables

The AccountChooser ac.js file establishes the following javascript variables:

name description
accountchooser A javascript variable defined by ac.js that can be manipulated by the site.
accountchooser.Api A javascript variable which is a child element of the accountchooser variable. This object represents the AccountChooser javascript API.

4.2. AccountChooser JavaScript Methods

The AccountChooser ac.js file establishes the following javascript variables:

name description
accountchooser.Api.init(config) Initialize the AccountChooser client API object and return it.
accountchooser.Api.prototype.select(opt_accounts, opt_clientConfig) Show account selecting page in AccountChooser and allow the user to select or add an account.
accountchooser.Api.prototype.store(accounts, opt_clientConfig) Store account(s) into AccountChooser.
accountchooser.Api.prototype.update(account, opt_clientConfig) Update an account in AccountChooser.
accountchooser.Api.prototype.checkDisabled(callback) Check if the Account Chooser is disabled.
accountchooser.Api.prototype.checkEmpty(callback) Check if the Account Chooser is empty.
accountchooser.Api.prototype.checkAccountExist(account, callback) Check if the specified account exists in the AccountChooser.
accountchooser.Api.prototype.checkShouldUpdate(account, callback) Check if the specified account needs to be updated.
accountchooser.Api.prototype.changePopupModeTo(popupMode) Change the popup mode to the specified mode.
accountchooser.Api.prototype.setPopupWindow(popupWindow) Set the popup window to specified window.
accountchooser.Api.prototype.getPopupWindow() Get the current popup window.
accountchooser.Api.prototype.closePopupWindow() Close the popup window, if open.

4.3. AccountChooser Initialization

The AccountChooser object is initialized by calling a configuration object to the accountchooser.Api.init(config) method. The config object has the following fields:

name type description
config.popupMode boolean Whether or not to use AccountChooser in popup window. If false or unspecified, redirect mode is used.
config.popupWindow object The popup window object. If not specified, the client will create a new popup window to open AccountChooser. Otherwise, the popupWindow is used.
config.popupWidth number The width of the new popup window.
config.popupHeight number The height of the new popup window.
config.keepPopup boolean Whether to keep the popup window after the user finishes the action in AccountChooser. If false or unspecified, the popup window will be closed automatically.
config.clientCallbackUrl string The return-to URL from AccountChooser in redirect mode. if unspecified, the current URL (window.location.href) is used. After AccountChooser redirects back to this URL, the corresponding callback function is called with a response object. See config.callbacks.
config.positiveCallbackUrl string If specified and the user performs positive action (i.e., confirm to add/update accounts), this one is used instead of clientCallbackUrl. No callback is needed since the URL itself represents the result.
config.negativeCallbackUrl string If specified and the user performs negative action (i.e., cancel to add/update accounts), this one is used instead of clientCallbackUrl. No callback is needed since the URL itself represents the result.
config.providers array An array of supported identity providers (IDP). By convention, each IDP is represented by its top level domain. i.e., ["google.com", "yahoo.com"]. If specified and not empty, AccountChooser will show accounts which are associated with the IDP(s).
config.language string The language that the client wants to use. Default is "en".
config.ui object The customized UI settings.
config.ui.favicon string URL of the website's favicon. If specified, AccountChooser will show it on the browser's tab.
config.ui.title string The window title. If specified, AccountChooser will show it on the browser's tab.
config.ui.branding string URL of the website's branding content. If specified, AccountChooser will retrieve and show it on the account selecting page.
config.callbacks object An object that maps each response type to a callback function.
config.callbacks.empty function If specified, the callback will be invoked when there's no response from AccountChooser. It takes no argument and only gets invoked once after the page is loaded.
config.callbacks.select function If specified, the callback will be invoked when there's a select response from AccountChooser. See the example below for format.
config.callbacks.store function If specified, the callback will be invoked when there's a store response from AccountChooser. See the example below for format.
config.callbacks.update function If specified, the callback will be invoked when there's an update response from See the example below for format.

4.4. Show the AccountChooser

Your Site can display the AccountChooser by calling the accountchooser.Api.prototype.select(opt_accounts, opt_clientConfig) with its initialized accountchooser.Api object.

The opt_accounts parameter is an optional array of accounts. If provided, the AccountChooser will show the accounts in the array along with those already stored in the AccountChooser.

The opt_clientConfig object provides additional options that only apply to this method calls. The object MAY contain any of the following fields:

name type description
opt_clientConfig.keepPopup boolean Overwrite the global configuration value in this call. The global one remains unchanged.
opt_clientConfig.clientCallbackUrl string Overwrite the global configuration value in this call. The global one remains unchanged.
opt_clientConfig.providers array Overwrite the global configuration value in this call. The global one remains unchanged.
opt_clientConfig.language string Overwrite the global configuration value in this call. The global one remains unchanged.

4.5. Saving Account Records

The accountchooser.Api.prototype.store(accounts, opt_clientConfig) method adds the accounts specified to the AccountChooser storage for future use by the user. The accounts parameter MUST be an array of one or more accounts.

The opt_clientConfig object provides additional options that only apply to this method calls. The object MUST have the following fields:

name type description
opt_clientConfig.keepPopup boolean Overwrite the global configuration value in this call. The global one remains unchanged.
opt_clientConfig.clientCallbackUrl string Overwrite the global configuration value in this call. The global one remains unchanged.
opt_clientConfig.positiveCallbackUrl string Overwrite the global configuration value in this call. The global one remains unchanged.
opt_clientConfig.negativeCallbackUrl string Overwrite the global configuration value in this call. The global one remains unchanged.
opt_clientConfig.silent boolean Whether to do a silent account storing. If the site performing the action is the account bootstrapping domain for the browser, the account(s) will be stored into AccountChooser without user consent. Otherwise, the account bootstrapping domain config page is shown to the user.
opt_clientConfig.language string Overwrite the global configuration value in this call. The global one remains unchanged.

The user will be redirected to the AccountChooser to confirm or cancel the account storage. After the user action, they will be redirected to the clientCallbackUrl, and the AccountChooser will invoke the callback handler registered at initialization. The callback function looks like:

function storeHandler(result, error) { … }

If any error occurs, the result is undefined and the error is a JSON-RPC error object. Otherwise, the result is either {stored: true} or {stored: false}. If the positiveCallbackUrl is specified and the user confirms to store the account(s), AccountChooser will redirect back to positiveCallbackUrl instead of clientCallbackUrl, and the callback handler will not be invoked. The same rule applies to negativeCallbackUrl as well.

4.6. Update Account Record

The accountchooser.Api.prototype.update(accounts, opt_clientConfig) method updates an account stored in the AccountChooser. The account parameter MUST be an Account Record.

The opt_clientConfig object provides additional options that only apply to this method calls. The object MUST have the following fields:

name type description
opt_clientConfig.keepPopup boolean Overwrite the global configuration value in this call. The global one remains unchanged.
opt_clientConfig.clientCallbackUrl string Overwrite the global configuration value in this call. The global one remains unchanged.
opt_clientConfig.positiveCallbackUrl string Overwrite the global configuration value in this call. The global one remains unchanged.
opt_clientConfig.negativeCallbackUrl string Overwrite the global configuration value in this call. The global one remains unchanged.
opt_clientConfig.silent boolean Whether to do a silent account storing. If the site performing the action is the account bootstrapping domain for the browser, the account(s) will be stored into AccountChooser without user consent. Otherwise, the account bootstrapping domain config page is shown to the user.
opt_clientConfig.language string Overwrite the global configuration value in this call. The global one remains unchanged.

The user will be redirected to the AccountChooser to confirm or cancel the account update. After the user action, they will be redirected to the clientCallbackUrl, and the AccountChooser will invoke the callback handler registered at initialization. The callback function looks like:

function updateHandler(result, error) { … }

If any error occurs, the result is undefined and the error is a JSON-RPC error object. Otherwise, the result is either {updated: true} or {updated: false}. If the positiveCallbackUrl is specified and the user confirms to update the account, AccountChooser will redirect back to positiveCallbackUrl instead of clientCallbackUrl, and the callback handler will not be invoked. The same rule applies to negativeCallbackUrl as well.

4.7. Check AccountChooser Status

The accountchooser.Api.prototype.checkDisabled(callback)and accountchooser.Api.prototype.checkEmpty(callback) javascript methods check if the AccountChooser is disable or empty, respectively.

The callback parameter MUST be a callback function which takes one boolean parameter. The result of the check will be passed to this parameter in the callback.

If the AccountChooser does not contain any Account Records, then the accountchooser.Api.prototype.checkEmpty(callback) method will invoke the callback function with the parameter set to true.Otherwise, the callback function will be invoked with the parameter set to false.

If the AccountChooser has been disabled, then the accountchooser.Api.prototype.checkDisabled(callback) method will invoke the callback function with the parameter set to true. Otherwise, the callback function will be invoked with the parameter set to false.

4.8. Check Account Record Status

The accountchooser.Api.prototype.checkAccountExist(account, callback)and accountchooser.Api.prototype.checkAccountShouldUpdate(account, callback) javascript methods check if the Account Record exists in the AccountChooser, or should be updated, respectively.

The callback parameter MUST be an Account Record, and specifies which Account Record will be checked.

The callback parameter MUST be a callback function which takes one boolean parameter. The result of the check will be passed to this parameter in the callback.

If the Account Record specified by account exists in the AccountChooser, then the accountchooser.Api.prototype.checkAccountExist(account, callback) method will invoke the callback function with the parameter set to true.Otherwise, the callback function will be invoked with the parameter set to false.

If an Account Record with the same email field as account exists in the AccountChooser and either the old photoUrl does not match account.photoUrl, or the old displayName does not match account.displayName, then the accountchooser.Api.prototype.checkAccountExist(account, callback) method will invoke the callback function with the parameter set to true.Otherwise, the callback function will be invoked with the parameter set to false.

4.9. Popup Window Managment

The popup window settings configured at initialization can be changed at anytime through the set up popup window management methods.

The mode can be changed with the accountchooser.Api.prototype.changePopupModeTo(popupMode). If popupMode is set to true, then the AccountChooser will be displayed in a popup window. If popupMode is set to false, then the AccountChooser will be displayed through a full page redirect.

The popup window can be changed with the accountchooser.Api.prototype.setPopupWindow(popupWindow). After this method has been called, the AccountChooser will be displayed as a popup in the popupWindow object.

The current object set as the popup window can be retrieved with the accountchooser.Api.prototype.getPopupWindow() method.

An open AccountChooser in popup mode can be closed with the accountchooser.Api.prototype.closePopupWindow() method.

5. Login with AccountChooser

The advanced AccountChooser Javascript API takes more work to integrate with your login flow, but can ultimately result in a smoother user experience. This section describes how to integrate your login low tihe the advanced AccountChooser Javascript API.

5.1. Initialize the AccountChooser

Before the site can interact with the AccountChooser, the Account Chooser javascript object MUST be initialized with the accountchooser.Api.init(config)method described in section 4.3.

5.2. Check AccountChooser Status

Through the advanced API, your site can check if there are any saved accounts in the AccountChooser without any screen flicker.

When a user begins the login process for your site, you may quickly query the state of the AccountChooser using the methods described in section 4.6. To provide the best experience, your site SHOULD verify that the AccountChooser contains one or more Account Records and has not been disabled by the user before attempting to display the AccountChooser.

If the AccountChooser has been disabled or does not contain any Account Records, your site SHOULD display its usual login fields.

5.3. Display the AccountChooser

Once you have verified the status of the AccountChooser, the site SHOULD display the Account Chooser by calling the accountchooser.Api.prototype.select(opt_accounts, opt_clientConfig) method, as described in section 4.4.

After the user selects an account or indicates to add one, AccountChooser will redirect back to theclientCallbackUrl and invoke the config.callbacks.select handler registered on initialization.

If any error occurs, the result parameter is undefined and the error parameter is a JSON-RPC error object. Otherwise, the result is either {addAccount: true}, which indicates the user clicks the add account button, or {account: {email: "", displayName: "", photoUrl: "", providerId: ""}. The site SHOULD commence the login flow for the account specified by email, and personalize the screen with the user’s Display Name and photo.

5.4. Save the Account Record

During login, the site SHOULD allow the user to specify if they would like their account to be saved, typically with a “remember me” button.

If the callback result contained {addAccount: true} and the user opted to save their account, then the site SHOULD attempt to save the account to the Account Chooser. First, the site should create an Account Record javascript object, which MUST include the email property and SHOULD include displayName, photoUrl, and providerId if available. Because a user must consent to adding an Account Record to their AccountChooser, there are two ways a site can attempt to save the record.

The accountchooser.Api.prototype.store(accounts, opt_clientConfig) method is the easiest way to save Account Record(s) to the AccountChooser. See section 4.5 for usage. Note that this method will display the Account Chooser again, so that the user can consent to saving their Account Record.

To avoid the consent screen at login time, the site can also save the Account Record on its own, such as within the user’s session cookie. When the user’s session expires and is prompted to sign into the site a second time, the site can put the saved Account Record into the opt_accounts parameter of the accountchooser.Api.prototype.select(opt_accounts, opt_clientConfig) method. If the user selects one of the opt_accounts Account Records, then it counts as consent to save the Account Record to their AccountChooser.

Authors' Addresses

T. Bray Google Inc.
N. Sakimura Nomura Research Institute
P. Dingle Ping Identity
D. Salama Google Inc.

Table of Contents