Credentials

The Credential Management API allows authorized Web applications to store and request user credentials (like login and password or federated login data) programmatically on behalf of the user. The API offers a replacement for browser built-in or 3rd-party password stores which allows the Web application to instrument when and how the credentials are stored and read, for example to offer automatic sign-in capability.

When retrieving the previously stored credential, the Web application may decide if the user mediation is expected. When mediation flag is set to silent, the credential will only be resolved if the user had previously stored the single credential for this application. With optional option set, the UI to choose the credential will appear unless there's a single credential stored. Finally, with required option, the UI will always be shown, regardless of the previously stored credentials existence.

API glimpse

credential = new PasswordCredential(form)
Creates the credential object based on the username and password data detected in a HTML <form> element.
credential = new PasswordCredential({id, password, name, iconURL})
Creates the credential object manually based on the data provided.
credential = new FederatedCredential({id, name, iconURL, provider, protocol})
Creates the credential object based on the federated login service specified with provider and protocol options.
navigator.credentials.store(credential)
Stores the credential provided for future access. Returns a Promise resolved when the credential is successfully persisted by the browser.
navigator.credentials.get({mediation})
Retrieves the previously stored credential from the browser, optionally with user mediation (UI). Returns a Promise resolved with fetched credential or null.
navigator.credentials.preventSilentAccess()
Ensures the user mediation is required on the next credential access request, effectively "logging out" the user.

Live Demo

Store your credentials:

User mediation:

  • function storeCredential() {
      event.preventDefault();
    
      if (!navigator.credentials) {
        alert('Credential Management API not supported');
        return;
      }
      
      let credentialForm = document.getElementById('credential-form');
      let credential = new PasswordCredential(credentialForm);
      navigator.credentials.store(credential)
        .then(() => log('Storing credential for <b>' + credential.id + '</b> (result cannot be checked by the website)'))
        .catch(err => log('Error storing credentials: ' + err));
    }
    
    function requestCredential() {
      if (!navigator.credentials) {
        alert('Credential Management API not supported');
        return;
      }
      
      let mediationValue = document.getElementById('credential-form').mediation.value;
      navigator.credentials.get({password: true, mediation: mediationValue})
        .then(credential => {
          let result = 'none';
          if (credential) {
            result = credential.id + ', ' + credential.password.replace(/./g, '*');
          }
          log('Credential read: <b>' + result + '</b>');
        })
        .catch(err => log('Error reading credentials: ' + err));
    }
    
    function preventSilentAccess() {
      if (!navigator.credentials) {
        alert('Credential Management API not supported');
        return;
      }
      
      navigator.credentials.preventSilentAccess()
        .then(() => log('Silent access prevented (mediation will be required for next credentials.get() call)'))
        .catch(err => log('Error preventing silent acces: ' + err));
    }
    
    function log(info) {
      var logTarget = document.getElementById('result');
      var timeBadge = new Date().toTimeString().split(' ')[0];
      var newInfo = document.createElement('p');
      newInfo.innerHTML = '<span class="badge">' + timeBadge + '</span> ' + info + '</b>.';
      logTarget.appendChild(newInfo);
    }
  • <div class="row">
    <div class="col-sm-6">
      <form id="credential-form" onsubmit="storeCredential(event)">
        <p><b>Store your credentials:</b></p>
        <p>
          <label>login: <input type="text" name="username" class="form-control" required autocomplete="username"></label>
          <label>password: <input type="password" name="password" class="form-control" required autocomplete="current-password"></label>
        </p>
        <p><button type="submit" class="btn btn-default">Store credential</button></p>
      
        <p class="user-mediation">
          <b>User mediation:</b><br/>
          <label><input type="radio" name="mediation" value="silent"> silent</label>
          <label><input type="radio" name="mediation" value="optional" checked> optional</label>
          <label><input type="radio" name="mediation" value="required"> required</label>
        </p>
        <p><button type="button" onclick="requestCredential()" class="btn btn-default">Request credential</button></p>
        <p><button type="button" onclick="preventSilentAccess()" class="btn btn-default">Prevent silent access (logout)</button></p>
      </form>
    </div>
    <div class="col-sm-6" id="result"></div>
    </div>

Resources