質問
Webサービスのログイン速度チェックを実装する必要があります。サービスはrubyにあり、データベースはMySqlです。
これを行うには悪い方法が想像できます。たとえば、すべてのログイン試行の時間と成功したかどうかを保存するテーブルがあり、ユーザーがログインを試みるたびに、最後の n ログイン試行についてそのテーブルを照会し、いくつかの単純なそれに対するアルゴリズム。ただし、これは明らかに明らかに非効率的です。ログイン試行ごとに、かなり大きなテーブルで選択と挿入が行われるため、システム全体の速度が低下します。
より良い方法は、 n の値が3などにハードコードされていることを示し、ユーザーテーブル(パスワード検証が保存されている場所)に n 列。最新の n ログイン試行を保持します。これにより余分なselectステートメントが削除され、ユーザーテーブルはおそらくログイン試行テーブルよりもはるかに短くなります。ただし、アルゴリズムが変更された場合に興味深い多くのデータが失われます。
この時点で、パスワード検証機能を備えたテーブルに単一のテキストフィールドを配置する構造のバリエーションに傾いています。このテキストフィールドには、ログイン試行レコードの配列であるシリアル化オブジェクトが保持されます。ログインしようとすると、そのフィールドは解析され書き換えられます。これにより、固定された n の問題が解決され、非常に大きなテーブルを照会する必要がなくなります。ただし、データベースからテキストフィールドを読み取ると、ディスクアクセスの特性が低下するため、結果としてソリューションが低下する場合があります。
最後に、別の可能性はMySqlのログファイルでバックアップされたデータベース(名前はわかりません)を使用することですが、ログファイルのクエリで効率的であると思われることを除いて、それについてはほとんど何も知りません。
スタックオーバーフローに関する私の質問は次のとおりです。業界では通常、ログイン速度チェックはどのように実装されていますか。
更新1:
速度チェックを定義する必要があります。ログイン試行の速度チェックは、連続した失敗の数と連続した失敗が発生した時間枠の両方を追跡します。最初の返信は、これらのプロパティを使用したソリューションを指し示しています。しかし、速度チェックの柔軟性を可能にするのに十分な情報を保持しているのだろうか。そのようなシステムを一度も構築したことがないので、私の懸念は、私がそれを構築し始めたときに考慮したいと思う速度チェックの重要な側面を見落としていることです...
解決
最終的に、John Bokerが提案したものに似たものを作成しました。ユーザーの認証に使用されるテーブルには、 failed_login_count
とDateTimeオブジェクトである first_failed_login
の2つの新しい列があります。ユーザーが正常にログインするたびに、 failed_login_count
は0にリセットされ、 first_failed_login
はまだの場合は null
にリセットされます。ログイン試行が失敗するたびに、 failed_login_count
が増分されます。 0の場合、 first_failed_login
は現在の時刻を取得します。ユーザーがログインを試みるたびに、パスワードを検証する前に速度チェックが行われます。 failed_login_count
が0より大きい場合、現在の時刻と first_failed_login
の時間差で割られます。その値が最大許容速度よりも大きい場合、速度チェックは失敗します。
さらに、将来のオフライン処理のために失敗したログイン試行と失敗した速度チェックを積極的にログに記録するため、ブルートフォースアカウントの試行を追跡し、それらの計算に必要な詳細を追跡することなくログイン試行の失敗が多すぎるアカウントを無効にできますデータベース自体に。
他のヒント
asp.netのデフォルトのメンバーシッププロバイダーには、FailedPasswordAttemptCountと呼ばれるユーザーテーブルの1つの列があると思います。失敗した試行ごとにインクリメントし、成功すると0にリセットされます。その列とLastLoginAttemptTimestamp列を使用すると、一定期間ユーザーをロックアウトできます。
これを行うには悪い方法が想像できます。にとって たとえば、格納するテーブルがあります すべてのログイン試行の時間と 成功したかどうか、そして ユーザーがログインを試みる時間、クエリ 最後のnログインのテーブル いくつかの簡単なアルゴリズムを試みて実行する それに対して。それはかなりはっきりと思われる ただし、非常に非効率的です。毎 ログイン試行は、選択と かなり大きなテーブルに挿入します システム全体の速度が低下します。
最大速度がわかっている場合、「ログイン失敗」のエントリの負荷を簡単に消去できます。通常のテーブル(1日あたり数万回のログイン失敗が予想される場合を除き、1日で十分です)。
1日あたりのログイン数とログイン失敗回数を考慮することをお勧めします。