ここで説明する更新の一部については、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
に公開され、ユーザーが次のいずれかを選択できます。
Chrome 60
Chrome 60 では、 Credential Management API:
カスタム
fetch()
関数でパスワードを取得する必要がなくなったため、 まもなくサポート終了となります。navigator.credentials.get()
が列挙型mediation
を受け入れるようになりました ブール値のフラグunmediated
ではなく、新しいメソッド
navigator.credentials.create()
認証情報オブジェクトを非同期で作成します。
機能検出について確認が必要です
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
を使用することをおすすめします。
navigator.credentials.get()
が列挙型メディエーションを受け入れるようになりました
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 がすでに実装されていますか?移行ガイドのドキュメントをご覧ください 手順に沿って新しいバージョンにアップグレードできます。