🔐

組織IDも保存できる!パスワードマネージャー(を使っている人)に優しいログインフォームの作り方

に公開

パスワードマネージャーに組織IDが保存されなくて毎回手入力してる K@zuki. です。

いや、正確には保存されなかったんですけどね。

今回は、組織IDも含めてきちんと保存・入力されるパスワードマネージャーを使っている人に優しいログインフォームの実装方法を紹介します。

要約

  • 基本的なログインフォーム(メアド+パスワード)なら特別な設定不要
  • 組織IDなど追加フィールドがある場合はautocomplete属性を設定
    • autocomplete="off"は意図がない限り使わない
  • 実装コストは低いのにセキュリティ効果は大

そもそもの問題

toB SaaSのサービスを作るわけでなければ、パスワードマネージャーの存在を意識してフォームを作ったことがありませんでした。
というよりも意識しなくてもパスワードマネージャーが自動で入力してくれるので、特に気にしたこともなかったんです。

メアド・パスワードだけでなく組織IDも必要なログインフォームを作ると、パスワードマネージャーが組織IDを認識してくれないことに気づきました。
例えば、以下のようなフォームです。

<!-- 組織ID + メールアドレス + パスワード -->
<form>
  <input type="text" name="organization_slug" placeholder="組織ID" />
  <input type="email" name="email" placeholder="メールアドレス" />
  <input type="password" name="password" placeholder="パスワード" />
</form>

パスワードマネージャーを使うと、メアドとパスワードは自動入力されるんですが、組織IDだけは毎回手入力することになると思います。
実際にこういったサービスがtoB SaaSではよくあるので、イメージがつきやすいと思います。

この一手間が地味にめんどくさいですよね。
でも、実はこれ、ちょっとした設定で解決できます。

基本的なログインフォームなら何もしなくていい

まず大前提として、メアド+パスワードだけの普通のログインフォームなら、特別な設定は不要です。

<!-- これだけで大抵のパスワードマネージャーは動作する -->
<form>
  <input type="text" name="username" />
  <input type="password" name="password" />
  <button type="submit">ログイン</button>
</form>

パスワードマネージャーは一般的なフィールド名(usernameやpassword)を認識して、適切に保存・自動入力してくれます。

  • username/email/passwordという名前のフィールド
  • type="password"のフィールド
  • フォームの構造(username + password)のパターン

しかし、組織IDのような標準的じゃないフィールドがあると話は別です。

autocomplete属性で解決

サクッと解決策を紹介しますが、非常にシンプルです。
パスワードマネージャーは、autocomplete属性を使ってフィールドの役割を認識するケースが多いため、この属性を適切に設定するだけでOKです。

例えば、組織IDを入力するフィールドにautocomplete="organization"を設定します。

<form>
  <input 
    type="text" 
    name="organization_slug" 
    autocomplete="organization"
    placeholder="組織ID" 
  />
  <input 
    type="email" 
    name="email" 
    autocomplete="username"
    placeholder="メールアドレス" 
  />
  <input 
    type="password" 
    name="password" 
    autocomplete="current-password"
    placeholder="パスワード" 
  />
</form>

これだけで、パスワードマネージャーは組織IDも含めて保存・自動入力してくれるようになります。

実際のコード例

Rails (Slim) での実装

実際にSlimで使ってるコードはこんな感じです。

= form_with url: admin_login_path, method: :post, 
    local: true, id: "login-form" do |f|
  
  = render FormInputComponent.new(
      form: f, 
      field_name: :organization_slug, 
      type: :text_field, 
      autocomplete: "organization"
    )
  
  = render FormInputComponent.new(
      form: f, 
      field_name: :email, 
      type: :email_field, 
      autocomplete: "username"
    )
  
  = render FormInputComponent.new(
      form: f, 
      field_name: :password, 
      type: :password_field, 
      autocomplete: "current-password"
    )

React/Next.jsでの実装

export function LoginForm() {
  return (
    <form action="/api/login" method="post">
      <input
        type="text"
        name="organization"
        autoComplete="organization"  // Reactではキャメルケース
        placeholder="組織ID"
      />
      <input
        type="email"
        name="email"
        autoComplete="username"
        placeholder="メールアドレス"
      />
      <input
        type="password"
        name="password"
        autoComplete="current-password"
        placeholder="パスワード"
      />
      <button type="submit">ログイン</button>
    </form>
  );
}

やっちゃいけないこと

autocomplete="off"

セキュリティのつもりで設定しがちですが、逆効果になる可能性があります。
ユーザーが弱いパスワードを使う原因になったり、手動入力の強制が原因でフィッシングサイトに引っかかったりするリスクもあります。

<!-- パスワードマネージャーを無効化してしまう -->
<input type="password" autocomplete="off" />

変なフィールド名

大体はなんとかしてくれますが、あまりにも変なフィールド名を使うとパスワードマネージャーが認識しにくくなります。

<!-- パスワードマネージャーが認識しにくい -->
<input type="text" name="login_field" />
<input type="password" name="pass_field" />

JavaScriptで貼り付け禁止

本当によく見かけるんですが、パスワードマネージャーも貼り付けを使うので動作しなくなります。
ユーザーが手動で入力することを強制するのは、セキュリティ的にもUX的にも良くありません。

// パスワードマネージャーの動作を妨げる
passwordInput.addEventListener('paste', (e) => {
  e.preventDefault();
});

動作確認のやり方

実装したら、以下のパスワードマネージャーで動作確認してみましょう。(1Password、Bitwarden、ブラウザ内蔵のパスワードマネージャー)
全てでの動作確認をしているわけではないですが、一般的なパスワードマネージャーでは問題なく動作するはずです。
確認するためのポイントは以下の通りです。

  • 新規登録時に組織IDも含めて保存されるか
    • パスワードマネージャーの保存データに組織IDが含まれているか
  • ログイン時に全フィールドが自動入力されるか
    • 成功していれば、メアド・パスワードと共に組織IDも入力される

これで問題がなければ、パスワードマネージャー(を使っている人に)優しいログインフォームの完成です。

実装してみた結果の感想

実際に実装してみたら、思った以上に快適になりました。

以前は、

  1. 組織IDを手動で入力(またはコピペ)
  2. パスワードマネージャーでメアドとパスワードを入力

といった手間がかかりましたが、今は、

  1. パスワードマネージャーで全部自動入力

地味な改善ですが、頻繁にログインする人にとっては大きな違いです。
こういった小さな改善が積み重なることで、ユーザー体験が向上します。

まとめ

パスワードマネージャーを使っている人に優しいログインフォームの実装方法を紹介しました。
そんなに難しいことをしていませんでしたね。

  • 基本的なフォームなら何もしなくてOK
  • 組織IDなど追加フィールドがある場合はautocomplete属性を設定
  • autocomplete="off"は使わない
  • 貼り付け禁止もやめる

実装コストは低いのに、セキュリティとUXの両方が向上します。
みなさんも組織IDが必要なサービスを作ってるなら、ぜひ試してみてください!

というか設定して!
まじで!
不便だから!

Discussion