トピックを検索
貼り付けられないワンタイムコードの入力欄
ログインの手順で6桁のコードを1文字ずつの6つの欄で求めるため、テキストメッセージからコードを貼り付けても最初の1桁しか入りません。
<input inputmode="numeric" maxlength="1"> 問題
6桁を覚えておくことや、1桁ずつ打つことが難しい人が、ある画面のコードを読んで別の画面に打ち直すことになります。
あるショップは、ログインに2段階目の確認を設けています。パスワードの後、6桁のコードをテキストメッセージ(SMS)で送り、1桁ずつの6つの欄を持つページを表示します。「Larkspurの確認コード:481902」というメッセージが届きます。コードをコピーして最初の欄に貼り付けると、4だけが入ります。各欄は1文字しか受け付けないため、ブラウザーは貼り付けたコードを最初の1桁に切り詰め、残りの5つの欄は空のままです。新しいメッセージからスマートフォンが候補に出すコードを選んでも、同じように入ることがあります。残る方法は、メッセージのコードを読み、1桁ずつ別の画面に打ち直すことだけです。
同じ手順は、ほかの形でもつまずきます。
- 欄は貼り付けを受け付けるが、ちょうど6桁のときだけなので、一部のメッセージのように途中に空白があるコードをコピーすると何も起きない。
- 1つのコード欄に
maxlength="6"があり、「481 902」とコピーしたコードが「481 90」に切られて受け付けられない。 - 1桁ずつ4つの欄で求めるPINを、パスワードマネージャーが入力できない。
達成基準3.3.8「アクセシブルな認証(最低限)」はレベルAAで、WCAG 2.2で新しく加わりました。ログインのどの段階も、パスワードを覚えることやコードを書き写すことのような認知機能テストに頼ってはいけません。ただし、別のログイン方法があるか、パスワードマネージャーやコピーと貼り付けのような助けがあれば構いません。メッセージのコードを打ち込むことは書き写しです。達成基準の解説書は、確認コードを手で打ち込ませるサービスは適合しないとし、少なくともコードを貼り付けられる必要があるとしています。
欄に分けた入力は、失敗例F109に当たります。1文字ずつ欄に入れるコードは不適合です。ただし、コード全体を最初の欄に貼り付けられ、ほかの欄が自動で埋まる場合は除きます。貼り付けを止める欄も同じく不適合です。打ち込む以外の入れ方がなくなるからです。どちらも、メールで届くログイン用のリンクのように、書き写しのいらない別の方法を同じログインで選べるなら適合します。
この基準が対象にするのは、コードをページに入れることで、コードを本人に届けることではありません。ログインする端末にコードが届くか、別の端末からそこへコピーできるかは、この基準の対象外です。
スマートフォンでは、メッセージとページが別のアプリにあります。コードを打つにはその間を何度も行き来することになり、その間もページではタイマーが進みます。
10グループ中4グループに影響
- 全盲 (影響あり)
- 弱視 (影響あり)
- 色覚 (影響なし)
- ろう (影響なし)
- 難聴 (影響なし)
- 発話 (影響なし)
- 手の操作 (影響あり)
- 届く範囲・力 (影響なし)
- 認知 (影響あり)
- 光過敏 (影響なし)
- 言語・認知・学習の能力が限られる 計算障害のある人や、短い間覚えておくことが苦手な人は、メッセージとページを行き来しながら6桁を覚えておき、1欄ずつ打ち直す必要があります。数字を1つ入れ違えればコードは違い、何度か間違えるとアカウントがロックされることもあります。
- 手の操作が限られる 音声入力は読み上げたコードをたいてい一度に入力するため、最初の欄には最初の1桁しか残りません。スイッチやスクリーンキーボードの利用者は、貼り付けなら一度で済むところを、6桁を1つずつ選ぶことになります。
- 視覚を使わない スクリーンリーダー利用者は、メッセージとページを見比べられません。一度で済むはずの貼り付けが最初の1桁で止まるため、コードを聞いて覚え、ページに戻って打つしかなく、その間もコードの有効期限は迫ります。
- 視覚が限られる 画面拡大ソフトの利用者は、メッセージと欄の間を行き来し、コードを数桁ずつ読んで、そのたびに今どこまで入れたかを探し直します。
どの欄にもラベルがあるため、axeなどの自動チェックは合格にします。EaseWebの診断は、ページのどこも貼り付けを受け取らない1文字ずつの欄の並びを報告します。そこでは、ブラウザーがどんな貼り付けも1文字に切り詰めるからです。また、試しの貼り付けを取り消し、何も入れないコードの欄も報告します。欄が独自に貼り付けを扱っていて、試しの貼り付けが各欄に分かれない場合は、確認の依頼を出します。診断が貼り付けるのは2桁だけで、コード全体は貼り付けません。全桁が入ると自動で送信され、実際のアカウントで失敗した試行として数えられることがあるためです。実際のコードは人が試す必要があります。診断には、コードが届くか、スマートフォンが候補に出すかは分かりません。AIのコードアシスタントに「OTPの入力欄」を頼むと、maxlength="1" の6つの欄を作り、1桁打つごとに次の欄へ移るようにして、貼り付けはまったく扱わないことがよくあります。
試してみる
スマートフォンの「コードをコピー」を押し、Ctrl+Vかコンテキストメニューで、ログインのページにコードを貼り付けてください。
ウィンドウの下の欄に、入った内容が出ます。ここでコピーできない場合は、メッセージのコードを選択して自分でコピーしてください。
問題あり 修正できますか?
入った内容: ······
修正方法
コードを丸ごと受け取ります。1つの欄にするか、貼り付けたコードを各欄に分けます。
- 1貼り付け、自動入力、音声入力したコードが、一度で全部入るようにする。
- 2貼り付けを取り消さず、コードの欄に maxlength="1" を付けない。
- 3最後の桁が入ったときではなく、ボタンが押されたときにコードを送る。
<p id="code-label">Enter the 6-digit code we sent to your phone</p><div class="code-boxes" role="group" aria-labelledby="code-label"> <input inputmode="numeric" maxlength="1" aria-label="Digit 1"> <input inputmode="numeric" maxlength="1" aria-label="Digit 2"> <input inputmode="numeric" maxlength="1" aria-label="Digit 3"> <input inputmode="numeric" maxlength="1" aria-label="Digit 4"> <input inputmode="numeric" maxlength="1" aria-label="Digit 5"> <input inputmode="numeric" maxlength="1" aria-label="Digit 6"></div>コード全体を受け取る1つの欄
<label for="code">Security code</label><p id="code-hint">We sent a 6-digit code to your phone. It works for 15 minutes.</p><input id="code" name="code" type="text" inputmode="numeric" autocomplete="one-time-code" spellcheck="false" aria-describedby="code-hint"><button type="submit">Continue</button>maxlength="1" があると、貼り付けたコードも、自動入力や音声入力のコードも、スクリプトの input ハンドラーが受け取る前にブラウザーが最初の1文字に切り詰めます。残りをほかの欄に分けるものがないため、コードは1桁ずつ打ち込むしかありません。
コードは、ほかの文字と同じように入ります。キーボードやコンテキストメニューからの貼り付けも、音声入力も、ブラウザーの自動入力も使えます。autocomplete="one-time-code" で欄の目的をブラウザーに伝えるため、Safariのように対応するブラウザーは、新しいメッセージのコードをキーボードの上に候補として出せます。inputmode="numeric" で、スマートフォンでは数字のキーパッドが出ます。maxlength はないため、「481 902」と貼り付けても入ります。サーバーは、空白とハイフンを除いてからコードを確かめます。どれにもスクリプトはいりません。
どちらも3.3.8を満たします。1つの欄にしてください。スクリプトなしで同じ役目を果たし、貼り付け、スマートフォンが候補に出すコード、音声入力、パスワードマネージャーのすべてをブラウザーが扱うため、どれも動きます。欄に分けると、そのそれぞれを正しく扱うスクリプトが必要です。スクリーンリーダーでも、6つではなく1つの欄として一度で読まれます。欄に分けるのは、デザインを変えられない場合だけにし、その場合は上のように、複数の文字の入力をすべて各欄に分けてください。
コードに type="number" は使わないでください。コードは数量ではありません。ブラウザーはそこでは maxlength を無視し、矢印キーで値が増減し、ハイフンの入ったコードを貼り付けると数でないとして捨てられます。inputmode="numeric" を付けたテキスト欄を使い、英字が入るコードでは inputmode を省きます。
コードは、ボタンかEnterキーで利用者が送るようにします。最後の桁が入った瞬間に送信するフォームは、そうなることを前もってページで伝えていない限り、3.2.2の不適合(失敗例F36)になります。数字を1つ間違えると、確かめる前に失敗した試行になってしまいます。
コードには時間を与えてください。30秒で切れるコードは制限時間です。2.2.1の解説書は、セキュリティのために有効期限を設けたログイン用のコードは必要不可欠とみなされ、この基準の対象外になりうるとしていますが、ゆっくり打つ人や、スクリーンリーダーでアプリを行き来する人には、ずっと長い時間が必要です。GOV.UKは15分としています。「新しいコードを送る」ボタンを、キーボードで使える本物のボタンとして置くと、コードが切れた人や届かなかった人の助けになります。
コードを間隔を空けて見せたいデザインでは、欄を分けずに1つの欄のスタイルで表します。letter-spacing と font-variant-numeric: tabular-nums で、6つの欄なしで数字の間が空きます。
PINなど、1文字ずつの欄で求めるほかのものも同じです。パスワードマネージャーは1つの欄なら入力できても、6つの欄には入力できません。PINを覚えていられない人には、貼り付けや自動入力が必要です。メールで届くリンクやパスキーのように、書き写しのいらない別のログイン方法を用意することも3.3.8を満たしますが、コードの手順を使う人のために、その手順も貼り付けを受け付けるようにしてください。
AI コーディングアシスタントで修正しますか? このガイドを Markdown で取得、または全ガイドをコーディングエージェントで使う。
修正の確認
マウスを使わない5つの確認
確認方法: キーボード、スクリーンリーダー、タッチ、自動入力、音声入力
OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。ログインの流れやコードの部品を変更した際は、再度確認します。
制限
このサンプルは、どのログインでも同じ結果になることを保証するものではありません。例はテキストメッセージで送るコードです。認証アプリやメールのコードも、同じように貼り付けを確かめてください。この基準は、コードを送る経路を指定していません。ログインする端末にコードが届くかどうかも対象外です。貼り付けを拒むパスワード欄や解かせるパズルなど、ログインのほかの部分も同じ基準の対象です。利用者が頼る人や道具と一緒に、ログイン全体を確認してください。
よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。
コードを更新しても、使いやすさを保つために
ガイドの内容を、コーディングエージェントやCIで使える開発ルールにまとめます。更新後は、キーボードとスクリーンリーダーで再テストし、問題が再発していないか確認します。