ブラウザのクレデンシャル管理と連携するCredential Managementを試す

Credential Management

クレデンシャル管理機能と連携するためのAPI仕様「Credential Management」がW3Cで議論されています。
https://www.w3.org/TR/credential-management/


ブラウザは、Webサイトにログインするためのユーザ名・パスワードといった資格情報(クレデンシャル)を独自に管理しています。そしてログインフォームなどを検出すると自動入力等も行います。
Credential Managementでは、このブラウザが持つクレデンシャル管理機能とWebサイト側が連携する仕組みを提供し、ユーザがスムーズにログイン処理を行えるようになります。


JavaScriptからクレデンシャルをストアさせたり、とりだしてログイン処理を行ったりできるようになります。
例えば、まずはストアされているクレデンシャルを用いてログインを試み失敗した時のみログインフォームを案内するような事も出来るようになります。


また、パスワードだけでなく、OpenID ConnectといったWebサイトが信頼するFederated Identity Providerを利用する形でのログインもCredential Managementの提供するAPIで利用できます。


試す

ChromeのCanaryでは既にCredential Managementに対応しているので簡単に動作確認をしてみた
https://asnokaze.com/demo/credential-management.html (Chrome52以上。実際のログイン処理は省略)

  • usernameとpasswordを入れて送信を行うと、クレデンシャルのストア処理が走る


普段見かける通知と同じだが、JavaScriptからストア処理を行ったことにより確認が行なわれる

  • "use Credential Management"をクリックすると、JavaScriptからブラウザにストアされてるクレデンシャルを取得する。


JavaScriptからクレデンシャルの取得する際、ブラウザは選択画面を表示する


続いて簡単なコード的な話

クレデンシャルのストア

ログインフォームでログインを行う際に、クレデンシャルのストアも行う


ログインフォーム

  <form method="GET" id="theForm">
    <label for="username">Username</label>
    <input type="text" name="username" id="username" autocomplete="username" placeholder="username">
    <label for="password">Password</label>
    <input type="text" name="password "id="password" autocomplete="current-password" placeholder="password">
    <input type="submit">
  </form>


JavaScript

document.querySelector('#theForm').addEventListener("submit", e => {
    if (navigator.credentials) {
        e.preventDefault();
        var c = new PasswordCredential(e.target);
        var init = { method: "POST", credentials: c };
   
        // ログイン処理
        fetch(e.target.action, init).then(r => {
            if (/* レスポンスを確認し、ログインに成功してたら */)
                  navigator.credentials.store(c);
        });
  }                                                                                 
});

formDataより、PasswordCredentialでオブジェクトを生成する。その後ログインに成功したらnavigator.credentials.storeでクレデンシャルのストアを行う

クレデンシャルの取得

そのサイトに関連付けられたクレデンシャルが存在する場合は、ストアからクレデンシャルの取得しログイン処理を行うことも出来る。

navigator.credentials.get({ "password": true }).then(
    function(credential) {
        if (!credential) {
            // クレデンシャルの取得に失敗した。
            // ユーザによって拒否されたか、クレデンシャルがストアされてない
            return;
        }

        //ログイン処理
        if (credential.type == "password") {
            fetch("https://example.com/loginEndpoint", { credentials: credential, method: "POST" })
              .then(function (response) {
              // ログインに成功したらユーザに通知する
          });

        }
    }
});                                                              

navigator.credentials.getを実行すると、ブラウザによってクレデンシャルの選択画面が表示されます。
ユーザが選択したクレデンシャルを用いてログイン処理を行ってやることが出来ます。

ちゃんとしたデモ

自分で試してから、ちゃんとしたデモサイトがあるのを知った...
Facebookログインなどのデモもありしっかりしている

https://credential-management-sample.appspot.com/


コチラのドキュメントも非常に参考になります
https://developers.google.com/web/updates/2016/04/credential-management-api?hl=ja