ユーザーをログインさせるには、ブラウザのパスワード マネージャーから認証情報を取得し、それらを使用してユーザーを自動的にログインさせます。複数のアカウントを持つユーザーが、Account Chooser を使用して 1 回タップするだけでアカウントを選択できるようにします。
自動ログイン
自動ログインは、ウェブサイトのどこでも(トップページだけでなく、他の子ページでも)発生する可能性があります。これは、ユーザーが検索エンジンを介してウェブサイトのさまざまなページにアクセスする場合に便利です。
自動ログインを有効にするには:
- 認証情報を取得します。
- お客様の認証を行います。
- UI を更新するか、パーソナライズされたページに進みます。
認証情報を取得する
認証情報を取得するには、navigator.credentials.get() を呼び出します。password または federated を指定して、リクエストする認証情報のタイプを指定します。
自動ログインには常に mediation: 'silent' を使用します。これにより、ユーザーが次の操作を行った場合に、プロセスを簡単に閉じることができます。
- 認証情報が保存されていない。
- 複数の認証情報が保存されている。
- ログアウトしている。
認証情報を取得する前に、ユーザーがすでにログインしているかどうかを確認してください。
if (window.PasswordCredential || window.FederatedCredential) {
if (!user.isSignedIn()) {
navigator.credentials.get({
password: true,
federated: {
providers: ['https://accounts.google.com'],
},
mediation: 'silent',
});
// ...
}
}
navigator.credentials.get() によって返される Promise は、認証情報オブジェクトまたは null で解決されます。PasswordCredential か FederatedCredential かを判断するには、オブジェクトの .type プロパティを確認します。このプロパティは password または federated になります。
.type が federated の場合、.provider プロパティは ID プロバイダを表す文字列です。
お客様を認証する
認証情報を取得したら、認証情報の種類(password または federated)に応じて認証フローを実行します。
}).then(c => {
if (c) {
switch (c.type) {
case 'password':
return sendRequest(c);
break;
case 'federated':
return gSignIn(c);
break;
}
} else {
return Promise.resolve();
}
Promise が解決されたら、認証情報オブジェクトを受け取ったかどうかを確認します。表示されない場合は、自動ログインができなかったことを意味します。 自動ログイン プロセスをサイレント モードで閉じます。
UI を更新する
認証が成功した場合は、UI を更新するか、ユーザーをパーソナライズされたページに転送します。
}).then(profile => {
if (profile) {
updateUI(profile);
}
認証エラー メッセージを表示することを忘れないでください
ユーザーが混乱しないように、認証情報オブジェクトの取得時に「ログインしています」という青色のトーストが表示されるようにする必要があります。
重要なヒント: 認証情報オブジェクトの取得に成功しても、ユーザーの認証に失敗した場合は、エラー メッセージを表示する必要があります。
}).catch(error => {
showError('Sign-in Failed');
});
}
}
完全なコードサンプル
if (window.PasswordCredential || window.FederatedCredential) {
if (!user.isSignedIn()) {
navigator.credentials
.get({
password: true,
federated: {
providers: ['https://accounts.google.com'],
},
mediation: 'silent',
})
.then((c) => {
if (c) {
switch (c.type) {
case 'password':
return sendRequest(c);
break;
case 'federated':
return gSignIn(c);
break;
}
} else {
return Promise.resolve();
}
})
.then((profile) => {
if (profile) {
updateUI(profile);
}
})
.catch((error) => {
showError('Sign-in Failed');
});
}
}
Account Chooser を使用したログイン
ユーザーがメディエーションを必要とする場合や、複数のアカウントを持っている場合は、Account Chooser を使用して、通常のログイン フォームをスキップしてログインできるようにします。次に例を示します。
アカウント選択ツールを介してログインする手順は、自動ログインの場合と同じですが、認証情報を取得する一環としてアカウント選択ツールを表示するための呼び出しが追加されます。
- 認証情報を取得し、Account Chooser を表示します。
- お客様を認証する。
- UI を更新するか、パーソナライズされたページに進みます。
認証情報を取得して Account Chooser を表示する
定義されたユーザー アクション(ユーザーが [ログイン] ボタンをタップしたときなど)に応じて、Account Chooser を表示します。navigator.credentials.get() を呼び出し、mediation: 'optional' または mediation: 'required' を追加してアカウント選択ツールを表示します。
mediation が required の場合、ユーザーには常にログイン用のアカウント選択ツールが表示されます。このオプションを使用すると、複数のアカウントを持つユーザーが簡単にアカウントを切り替えることができます。mediation が optional の場合、navigator.credentials.preventSilentAccess() 呼び出し後に、ログイン用のアカウント選択ツールがユーザーに明示的に表示されます。通常、これはユーザーがログアウトまたは登録解除を選択した後に自動ログインが行われないようにするためです。
mediation: 'optional' を示す例:
var signin = document.querySelector('#signin');
signin.addEventListener('click', e => {
if (window.PasswordCredential || window.FederatedCredential) {
navigator.credentials.get({
password: true,
federated: {
providers: [
'https://accounts.google.com'
]
},
mediation: 'optional'
}).then(c => {
ユーザーがアカウントを選択すると、Promise が認証情報で解決されます。ユーザーがアカウント選択ツールをキャンセルした場合、または保存されている認証情報がない場合、Promise は null で解決されます。その場合は、ログイン フォームのエクスペリエンスにフォールバックします。
ログイン フォームにフォールバックすることを忘れないでください
次のいずれかの理由により、ログイン フォームにフォールバックする必要があります。
- 認証情報は保存されません。
- ユーザーがアカウントを選択せずに Account Chooser を閉じた。
- API が利用できない。
}).then(profile => {
if (profile) {
updateUI(profile);
} else {
location.href = '/signin';
}
}).catch(error => {
location.href = '/signin';
});
完全なコードサンプル
var signin = document.querySelector('#signin');
signin.addEventListener('click', (e) => {
if (window.PasswordCredential || window.FederatedCredential) {
navigator.credentials
.get({
password: true,
federated: {
providers: ['https://accounts.google.com'],
},
mediation: 'optional',
})
.then((c) => {
if (c) {
switch (c.type) {
case 'password':
return sendRequest(c);
break;
case 'federated':
return gSignIn(c);
break;
}
} else {
return Promise.resolve();
}
})
.then((profile) => {
if (profile) {
updateUI(profile);
} else {
location.href = '/signin';
}
})
.catch((error) => {
location.href = '/signin';
});
}
});
連携ログイン
フェデレーション ログインを使用すると、ユーザーはウェブサイトのログイン情報を追加で覚える必要がなく、ワンタップでログインできます。
フェデレーション ログインを実装するには:
- サードパーティの ID でユーザーを認証する。
- ID 情報を保存します。
- UI を更新するか、パーソナライズされたページに進みます(自動ログインと同じ)。
サードパーティの ID でユーザーを認証する
ユーザーがフェデレーション ログイン ボタンをタップしたら、FederatedCredential を使用して特定の ID プロバイダの認証フローを実行します。
たとえば、プロバイダが Google の場合は、Google ログイン JavaScript ライブラリを使用します。
navigator.credentials
.get({
password: true,
mediation: 'optional',
federated: {
providers: ['https://account.google.com'],
},
})
.then(function (cred) {
if (cred) {
// Instantiate an auth object
var auth2 = gapi.auth2.getAuthInstance();
// Is this user already signed in?
if (auth2.isSignedIn.get()) {
var googleUser = auth2.currentUser.get();
// Same user as in the credential object?
if (googleUser.getBasicProfile().getEmail() === cred.id) {
// Continue with the signed-in user.
return Promise.resolve(googleUser);
}
}
// Otherwise, run a new authentication flow.
return auth2.signIn({
login_hint: id || '',
});
}
});
Google ログインでは、認証の証明として ID トークンが生成されます。
一般に、連携ログインは OpenID Connect や OAuth などの標準プロトコルを基盤として構築されています。フェデレーション アカウントで認証する方法については、それぞれのフェデレーション ID プロバイダのドキュメントをご覧ください。一般的な例としては、次のようなものがあります。
ID 情報を保存する
認証が完了すると、ID 情報を保存できます。ここに保存する情報は、ID プロバイダの id と、ID プロバイダを表すプロバイダ文字列です(name と iconURL は省略可能です)。この情報の詳細については、認証情報管理の仕様をご覧ください。
連携アカウントの詳細を保存するには、ユーザーの識別子とプロバイダの識別子を使用して、新しい FederatedCredential オブジェクトをインスタンス化します。次に、navigator.credentials.store() を呼び出して ID 情報を保存します。
フェデレーションが成功したら、FederatedCredential を同期的または非同期的にインスタンス化します。
同期アプローチの例:
// Create credential object synchronously.
var cred = new FederatedCredential({
id: id, // id in IdP
provider: 'https://account.google.com', // A string representing IdP
name: name, // name in IdP
iconURL: iconUrl, // Profile image url
});
非同期アプローチの例:
// Create credential object asynchronously.
var cred = await navigator.credentials.create({
federated: {
id: id,
provider: 'https://accounts.google.com',
name: name,
iconURL: iconUrl,
},
});
次に、認証情報オブジェクトを保存します。
// Store it
navigator.credentials.store(cred).then(function () {
// continuation
});
ログアウト
ログアウト ボタンがタップされたときにユーザーをログアウトします。まずセッションを終了してから、今後のアクセスのために自動ログインをオフにします。(セッションを終了する方法は、完全にあなた次第です)。
今後のアクセスで自動ログインをオフにする
navigator.credentials.preventSilentAccess() を呼び出します。
signoutUser();
if (navigator.credentials && navigator.credentials.preventSilentAccess) {
navigator.credentials.preventSilentAccess();
}
これにより、ユーザーが次回自動ログインを有効にするまで、自動ログインは行われません。 自動ログインを再開するには、ユーザーは Account Chooser からログインに使用するアカウントを選択して、意図的にログインすることを選択できます。その後、ユーザーが明示的にログアウトするまで、ユーザーは常に再度ログインされます。