Home | Send Feedback

Password auto-login with the Credential Management API

Published: 13. June 2019  •  java, javascript, spring, ionic

The Credential Management API is a browser API that allows a JavaScript application to interact with the integrated password manager.

With the Credential Management API, an application can store and retrieve passwords and federated login credentials and plays a role in the WebAuthn standard, where it stores public keys.

This blog post focuses on the password part of the interface and looks at how the API can support the traditional username/password login flow.

The following example is going to use the PasswordCredential object and calls the store() and get() methods to store password credentials into the password manager and to retrieve them.

This part of the Credential Management API is only implemented in Chrome at the time of writing (June 2019). Check out caniuse.com website for the current support: https://caniuse.com/#feat=credential-management

Demo application

This blog post shows you an example with a Spring Boot back end and an Ionic front end. The Spring Boot application uses Spring Security to implement a traditional session cookie-based form login process. I won't describe the back end further because the Credential Management API is a client-side API and works with any back-end technology.

You find the source code for the Spring Boot application on GitHub:
https://github.com/ralscha/blog2019/tree/master/credential/server


The Ionic application consists of a home page that users only see when they are logged in and a login page. The home page is protected with a CanActivate Angular route guard that checks if a user is logged in, if not, redirects to the login page.

demo app login demo app home

Here is the route configuration of the demo application.

const routes: Routes = [
  {path: '', redirectTo: 'home', pathMatch: 'full'},
  {
    path: 'home',
    canActivate: [() => inject(AuthGuard).canActivate()],

app-routing.module.ts

We add the recommended autocomplete attribute on the input fields to help the integrated password managers retrieve the correct fields on the login form.

      <ion-item>
        <ion-input [required]="true" autocomplete="username" label="Username" labelPlacement="stacked" name="username"
                   ngModel type="text"></ion-input>
      </ion-item>

      <ion-item>
        <ion-input [required]="true" autocomplete="current-password" label="Password" labelPlacement="stacked"
                   name="password" ngModel
                   type="password"></ion-input>
      </ion-item>

login.page.html

Because only Chrome has an implementation for PasswordCredential, we need to treat this feature as a progressive enhancement and add a feature detection check before accessing the API. This way, the application works in any browser, but only on Chrome, we are going to see the auto sign-in process.

if ((window as any).PasswordCredential) {

Chrome password settings

In Chrome, we have two settings that control the behavior of the integrated password manager. Open the settings page with chrome://settings/passwords.

chrome password settings

The first option enables or disables the password manager, and the second option enables auto sign-in. We will see how these options, especially the second one, affect the behavior of our demo application.

Without Credential Management API

We enable the password manager for the first test and disable the auto sign-in option (according to the screenshot above). Additionally, we don't access the Credential Management API in the application.

When we log in, Chrome's password manager recognizes the login request and opens a dialog where it offers to save the credentials.

chrome password login chrome password save password

If the user saves username and password and then opens the login page later, Chrome auto-fills the fields with the stored credentials, the user only has to click or tap on Login and is logged in.

chrome password auto fill

The password manager also supports multiple accounts per site. In that case, the user sees the following dialog when he focuses the username field.

chrome password multiple accounts

Credential Management API: Store Credentials

Next, we add code to our Ionic application that stores the password credential after the server successfully approves the login request.

  private async storePassword(username: string, password: string): Promise<Credential | null> {
    // @ts-ignore
    if (!window.PasswordCredential) {
      return Promise.resolve(null);
    }

    // @ts-ignore
    const cred = new window.PasswordCredential({
      id: username,
      password,
      name: username
    });
    return navigator.credentials.store(cred);
  }

auth.service.ts

We first add a feature detection check, so the application also runs on browsers that do not support this feature. The application then creates a PasswordCredential object and stores it with navigator.credentials.store into the password manager.

When we run the application, we see the exact behavior as before. The browser displays the Save Password dialog.

chrome password save password

Even with the explicit call to navigator.credentials.store, the user is still in charge of the workflow. He can deny the request or allow it. There is no option to store the credential silently.

The benefit of storing the credentials via JavaScript is that the browser no longer has to guess which are the correct fields (username and password) for logging in to this application.

Credential Management API: Retrieve Credentials

As mentioned at the beginning, we can not only store credentials we can also retrieve them from JavaScript with the navigator.credentials.get method.

With this capability, we can implement an auto sign-in solution that skips the login page when the password manager contains stored credentials for this site.

A good place for this to implement is the router guard. When the user navigates to the home page, Angular first executes the canActivate method of the guard.

The application first checks if the user is already logged in.

  canActivate():
    Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    if (this.authService.isLoggedIn()) {
      return true;
    }

    return this.authService.isAuthenticated().pipe(
      mergeMap(success => {
        if (success) {
          return of(true);
        }
        return this.tryAutoSignIn();
      }),
      map(success => {
        if (success) {
          return true;
        }
        return this.router.createUrlTree(['/login']);
      })
    );
  }

auth.guard.ts

If not, the code tries to fetch the password credentials from the password manager with navigator.credentials.get. If the method returns a credential, the application sends a login request to the server.

    // @ts-ignore
    if (!window.PasswordCredential) {
      return of(false);
    }

    // @ts-ignore
    return from(navigator.credentials.get({password: true}))
      .pipe(
        mergeMap(cred => {
            if (cred) {
              // @ts-ignore
              return this.authService.login(cred.name, cred.password);
            }
            return of(false);
          }
        )
      );
  }

auth.guard.ts

If you run this code and navigate to the home page (/ or /#/home), the Chrome browser displays the following dialog when our code calls the navigator.credentials.get method, and there are credentials stored.

chrome password save password

The method returns the credential if the user clicks on Sign in, and our application sends a login request to the server. If that request is successful, the application displays the home page.

If the user cancels the "Sign in as" dialog, the get method returns null, and the program displays the login page. The same happens when the browser does not support the PasswordCredential API.

Auto Login

This was already an improvement because we can skip the login page if credentials are stored in the browser, but the user still has to click on the Sign-in button.

The user can enable the second option (Auto Sign-in) on the password settings page to make this even more convenient.

chrome password auto sign-in

The call to navigator.credentials.get now no longer displays the "Sign in as" dialog and instead immediately returns either the stored credentials or null.

The browser displays the following dialog to inform the user that a sign-in occurred. chrome password auto sign-in

Note that when multiple accounts are stored for a site, the browser displays the "Sign in as" dialog, even when the "Auto Sign-in" feature is enabled.

chrome password multiple accounts


This concludes this tutorial about integrating the Credential Management API with a traditional username/password login flow.

See also the following two articles for more information about the API:


The source code for the demo application is hosted on GitHub:
https://github.com/ralscha/blog2019/tree/master/credential