この質問は私の以前の質問に続きます ユーザーを更新トークンで安全にサインインしたままにするには?
この前の質問で私が得たのは、次のものが必要だということです。
更新トークンは、1-1の関係でユーザーと共にDBに保持されます(1ユーザー= 1更新トークン)。ユーザーに対して更新トークンが作成されるたびに、以前のユーザーの永続化トークンがある場合はそれが置き換えられます。これにより、ハッカーは自分の仕事を行うための限られたウィンドウのみを持つことができます。
A1
と更新トークンR1
を受け取るA1
が有効期限に達すると、ハッカーは新しいアクセス/リフレッシュトークンを取得しますA2
/R2
盗まれた更新トークンR1
のおかげで:新しく作成された更新トークンR2
(ハッカーだけが持っている)は、DB(ユーザーが持っているもの)の以前のR1
を置き換えます。R1
が存在しないため、ユーザーは新しいアクセストークンの取得に失敗したため、再度サインインして、新しいアクセス/更新トークンA3
/R3
を取得します:新しく作成された更新トークンR3
(ユーザーだけが持っている)は、DB内の以前のR2
(ハッカーが持っているもの)を置き換えますA2
は期限切れになりますが、更新トークンR2
が存在しないため、新しいトークンを取得できません:トークンを再度盗む必要があります(もちろん、難しいと思われます)ここで私が疑問に思っているのは、ユーザーがこのメカニズムを使用して複数のデバイスから接続できるようにする方法ですか?たとえば、ユーザーが2つの異なるラップトップでサインインした場合、更新トークンは常にお互いを消去します...手がかりはありますか?
私の意見では、あなたが今質問している質問は、もはやセキュリティに関するものではなく、むしろ概念の実装により焦点を当てています。リフレッシュトークンによって攻撃者にとって困難になることがすでに確立されており、実装が機能しているように見えます。あなたが説明していることから、カスタムソリューションを利用しており、この機能を提供するOAuth2ライブラリ実装のようなものではありません。
ここで決定する必要があるのは、同じユーザーアカウントから複数のデバイス認証が必要かどうかです。ユーザーが1つのアカウントで複数のデバイスからサインインしたくない場合、おめでとうございます。ソリューションは既に機能しています。タイムアウト後に正しいリフレッシュトークンが含まれないため、古いデバイスからすぐにログアウトされます。
ユーザーが同じアカウントの複数のデバイスからサインインできるようにしたい場合は、残念ながらいくつかの変更が必要です。可能な解決策は、データベースにデバイス識別フィールドを追加し、デバイスごとに更新トークンを発行することです。
ジョーの答えに同意する
可能な解決策は、データベースにデバイス識別フィールドを追加し、デバイスごとに更新トークンを発行することです。
しかし、私はいくつかの実装の詳細を追加したいと思います。
IMOの最も堅牢で機能的なソリューションは、各ユーザーがデータベースに多数のレコードを持ち、それぞれに3つの列(access_token、refresh_token、device_id)があることです。
主なケースを調べてみましょう:
明確に理解しておくべきことの1つは、ハッカーがアクセス/リフレッシュトークンを盗んだ場合にのみ、リフレッシュトークンがあなたを救うことができますが、実際のパスワードは節約できません!彼がパスを取得した場合、問題が発生し、パスワードを復元するためのプロトコルを実装する必要があるためです(たとえば、電子メールやSMSの助けを借りて)。
PS期限切れになる可能性のあるrefresh_tokenを用意することをお勧めします。ケースを防ぐために、ジャッカーが古いデバイスから古いアクセスと参照トークンを失効させた場合、今は決して使用しません。
P.P.S期限切れのrefresh_tokenで行をクリーンアップする定期的なデータベースタスクがあると完璧です(おそらくそのために列refresh_tocken_expiration_dateを追加する必要があります)
P.P.P.S.私はセキュリティの専門家ではないので、より良い解決策があると思われる場合は、ぜひお話しさせていただきます。
読んでくれてありがとう、これが役に立てば幸いです)