登録フォームとログイン フォームはできる限りシンプルにします。
ログイン フォームの認証情報を保存して、ユーザーが再びアクセスするときに再ログインしなくて済むようにします。
フォームからユーザー認証情報を保存するには:
- フォームに
autocompleteを含めます。 - フォームの送信をブロックする。
- リクエストを送信して認証します。
- 認証情報を保存します。
- UI を更新するか、パーソナライズされたページに進みます。
フォームに autocomplete を含める
続行する前に、フォームに autocomplete 属性が含まれているかどうかを確認します。これにより、Credential Management API はフォームから id と password を見つけて、認証情報オブジェクトを作成できます。
また、Credential Management API をサポートしていないブラウザがそのセマンティクスを理解するのにも役立ちます。自動入力について詳しくは、Jason Grigsby のこちらの記事をご覧ください。
<form id="signup" method="post"> <input name="email" type="text" autocomplete="username email" /> <input name="display-name" type="text" autocomplete="name" /> <input name="password" type="password" autocomplete="new-password" /> <input type="submit" value="Sign Up!" /> </form> フォームの送信を防ぐ
ユーザーが送信ボタンを押しても、フォームが送信されないようにします。送信されると、ページが遷移します。
var f = document.querySelector('#signup'); f.addEventListener('submit', e => { e.preventDefault(); ページ遷移を防ぐことで、認証情報の真正性を確認しながら認証情報を保持できます。
リクエストを送信して認証する
ユーザーを認証するには、AJAX を使用して認証情報を伝えます。
サーバー側で、HTTP コード 200 または 401 で応答するエンドポイントを作成するか、既存のエンドポイントを変更して、登録、ログイン、パスワード変更が成功したかどうかをブラウザに明確にします。
次に例を示します。
// Try sign-in with AJAX fetch('/signin', { method: 'POST', body: new FormData(e.target), credentials: 'include', }); 認証情報を保存する
認証情報を保存するには、まず API が使用可能かどうかを確認し、フォーム要素を引数として同期または非同期で PasswordCredential をインスタンス化します。navigator.credentials.store() を呼び出します。API を使用できない場合は、プロファイル情報を次のステップに転送します。
同期の例:
if (window.PasswordCredential) { var c = new PasswordCredential(e.target); return navigator.credentials.store(c); } else { return Promise.resolve(profile); } 非同期の例:
if (window.PasswordCredential) { var c = await navigator.credentials.create({password: e.target}); return navigator.credentials.store(c); } else { return Promise.resolve(profile); } リクエストが成功したら、認証情報の情報を保存します。(リクエストが失敗した場合は認証情報情報を保存しないでください。保存すると、リピーターのユーザーが混乱します)。
Chrome ブラウザが認証情報(または連携プロバイダ)を取得すると、認証情報を保存するよう求める通知がポップアップ表示されます。
UI を更新する
問題がなければ、プロフィール情報を使用して UI を更新するか、パーソナライズされたページに進みます。
}).then(profile => { if (profile) { updateUI(profile); } }).catch(error => { showError('Sign-in Failed'); }); }); 完全なコード例
// Get form's DOM object var f = document.querySelector('#signup'); f.addEventListener('submit', (e) => { // Stop submitting form by itself e.preventDefault(); // Try sign-in with AJAX fetch('/signin', { method: 'POST', body: new FormData(e.target), credentials: 'include', }) .then((res) => { if (res.status == 200) { return Promise.resolve(); } else { return Promise.reject('Sign-in failed'); } }) .then((profile) => { // Instantiate PasswordCredential with the form if (window.PasswordCredential) { var c = new PasswordCredential(e.target); return navigator.credentials.store(c); } else { return Promise.resolve(profile); } }) .then((profile) => { // Successful sign-in if (profile) { updateUI(profile); } }) .catch((error) => { // Sign-in failed showError('Sign-in Failed'); }); }); ブラウザの互換性
PasswordCredential
navigator.credentials.store()