認証情報管理 API の最新情報

ここで説明する更新の一部については、Google I/O のセッションで説明していますが、 安全でシームレスなログイン: ユーザー エンゲージメントの維持:

Chrome 57

Chrome 57 では、 Credential Management API

別のサブドメインから認証情報を共有できます

別のサブドメインに保存されている認証情報を Chrome で Credential Management API。 たとえば、パスワードが login.example.com に保存されている場合、 www.example.com のスクリプトで、アカウント選択ツール ダイアログのアカウント アイテムの 1 つとして表示できます。

navigator.credentials.store() を使用してパスワードを明示的に保存する必要があります。 ユーザーがダイアログをタップして認証情報を選択したときに、 パスワードが渡されて現在のオリジンにコピーされます。

保存すると、そのパスワードを認証情報として使用できるようになります まったく同じオリジンの www.example.com 以降。

次のスクリーンショットでは、login.aliexpress.com に保存されている認証情報です。 m.aliexpress.com に公開され、ユーザーが次のいずれかを選択できます。

<ph type="x-smartling-placeholder">
</ph> 選択したサブドメインのログイン情報が表示されたアカウント選択ツール

Chrome 60

Chrome 60 では、 Credential Management API:

機能検出について確認が必要です

Credential Management API を使用して、パスワード ベースおよび 連携認証情報が使用可能である場合は、window.PasswordCredential または window.FederatedCredential は利用できます。

if (window.PasswordCredential || window.FederatedCredential) {
  // The Credential Management API is available
}

PasswordCredential オブジェクトにパスワードが追加されました

Credential Management API は、パスワードの処理に対して保守的なアプローチを採用しています。 JavaScript からパスワードを隠すため、開発者は PasswordCredential オブジェクトをサーバーに直接送信 fetch() API の拡張機能を介して検証できます。

しかし、この方法ではいくつかの制約がありました。 以下の理由により、デベロッパーが API を使用できないというフィードバックをいただきました。

  • パスワードを JSON オブジェクトの一部として送信する。

  • パスワードのハッシュ値をサーバーに送信する必要がありました。

セキュリティ解析を実施し、パスワードが隠されていると認識した後 期待したほど効果的にすべての攻撃経路を防御することはできませんでした。 変更を行うことにしました

Credential Management API に未加工のパスワードが含まれるようになりました。 平文でアクセスできるようにします。 認証情報をサーバーに配信するための既存の方法を使用できます。

navigator.credentials.get({
    password: true,
    federated: {
    providers: [ 'https://accounts.google.com' ]
    },
    mediation: 'silent'
}).then(passwordCred => {
    if (passwordCred) {
    let form = new FormData();
    form.append('email', passwordCred.id);
    form.append('password', passwordCred.password);
    form.append('csrf_token', csrf_token);
    return fetch('/signin', {
        method: 'POST',
        credentials: 'include',
        body: form
    });
    } else {

    // Fallback to sign-in form
    }
}).then(res => {
    if (res.status === 200) {
    return res.json();
    } else {
    throw 'Auth failed';
    }
}).then(profile => {
    console.log('Auth succeeded', profile);
});

カスタム取得はまもなくサポート終了となります

カスタム fetch() 関数を使用しているかどうかを確認するには、 PasswordCredential オブジェクトと FederatedCredential オブジェクトのどちらを使用しているかを確認する credentials プロパティの値として指定。例:

fetch('/signin', {
    method: 'POST',
    credentials: c
})

前のコードサンプルに示すように、通常の fetch() 関数を使用すると、 XMLHttpRequest を使用することをおすすめします。

Chrome 60 までは、 navigator.credentials.get() がオプションの unmediated プロパティを受け入れました 渡します例:

navigator.credentials.get({
    password: true,
    federated: {
    providers: [ 'https://accounts.google.com' ]
    },
    unmediated: true
}).then(c => {

    // Sign-in
});

unmediated: true を設定すると、ブラウザにアカウント選択ツールが表示されなくなります 渡されます。

フラグがメディエーションとして拡張されました。 ユーザー メディエーションは次のような場合に発生します。

  • ユーザーはログインに使用するアカウントを選択する必要があります。

  • ユーザーが明示的にログインする必要がある navigator.credentials.requireUseMediation() の呼び出し後。

mediation の値として、次のいずれかのオプションを選択します。

mediation ブール値フラグとの比較 動作
silent unmediated: true と等しい Account Chooser を表示せずに認証情報が渡されました。
optional unmediated: false と等しい アカウント選択ツールが表示される条件 preventSilentAccess() は以前に呼び出しました。
required 新しいオプション アカウント選択ツールを常に表示 ユーザーがアカウントを切り替えられるようにする場合に便利 ネイティブアカウントチューザの ダイアログを使用して

この例では Account Chooser を表示せずに認証情報が渡されます。 前述のフラグ unmediated: true と同等です。

navigator.credentials.get({
    password: true,
    federated: {
    providers: [ 'https://accounts.google.com' ]
    },
    mediation: 'silent'
}).then(c => {

    // Sign-in
});

requireUserMediation() の名前を preventSilentAccess() に変更しました

get() 呼び出しで提供される新しい mediation プロパティとうまく連携させるために、以下を行います。 navigator.credentials.requireUserMediation() メソッドの名前が navigator.credentials.preventSilentAccess()

名前を変更したメソッドでは、アカウント選択ツールを表示せずに認証情報を渡せない (ユーザー メディエーションなしで呼び出される場合もあります)。 これは、ユーザーがウェブサイトからログアウトしたり、登録を解除したりする場合に便利です。 次回アクセス時に自動的に再ログインされることを望んでいません。

signoutUser();
if (navigator.credentials) {
    navigator.credentials.preventSilentAccess();
}

新しいメソッド navigator.credentials.create() を使用して認証情報オブジェクトを非同期で作成する

認証情報オブジェクトを非同期で作成するオプションが追加されました これを新しいメソッド navigator.credentials.create() に置き換えます。 ここでは、同期と非同期の両方のアプローチの違いについて説明します。

PasswordCredential オブジェクトの作成

同期方法
let c = new PasswordCredential(form);
非同期アプローチ(新規)
let c = await navigator.credentials.create({
    password: form
});

または

let c = await navigator.credentials.create({
    password: {
    id: id,
    password: password
    }
});

FederatedCredential オブジェクトの作成

同期方法
let c = new FederatedCredential({
    id:       'agektmr',
    name:     'Eiji Kitamura',
    provider: 'https://accounts.google.com',
    iconURL:  'https://*****'
});
非同期アプローチ(新規)
let c = await navigator.credentials.create({
    federated: {
    id:       'agektmr',
    name:     'Eiji Kitamura',
    provider: 'https://accounts.google.com',
    iconURL:  'https://*****'
    }
});

移行ガイド

Credential Management API がすでに実装されていますか?移行ガイドのドキュメントをご覧ください 手順に沿って新しいバージョンにアップグレードできます。