まず、ユーザーについて既に知っていることを知る必要があります。明らかに、あなたはユーザー名と古いパスワードを持っています。他に何を知っていますか?メールアドレスはありますか?ユーザーのお気に入りの花に関するデータはありますか?
ユーザー名、パスワード、および作業用の電子メールアドレスがあるとすると、ユーザーテーブルに2つのフィールドを追加する必要があります(データベーステーブルであると仮定します)。new_passwd_expireという日付と文字列new_passwd_idです。
ユーザーの電子メールアドレスを持っていると仮定して、誰かがパスワードのリセットを要求すると、次のようにユーザーテーブルを更新します。
new_passwd_expire = now() + some number of days
new_passwd_id = some random string of characters (see below)
次に、そのアドレスのユーザーに電子メールを送信します。
親愛なるまあまあ
誰かが<あなたのウェブサイト名>のユーザーアカウント<ユーザー名>の新しいパスワードを要求しました。このパスワードのリセットをリクエストした場合は、次のリンクをたどってください。
http://example.com/yourscript.lang?update= < new_password_id >
そのリンクが機能しない場合は、http://example.com/yourscript.langにアクセスして、フォームに次のように入力できます。<new_password_id>
パスワードのリセットをリクエストしなかった場合は、このメールを無視してかまいません。
ありがとう、やだやだ
ここで、yourscript.langのコーディング:このスクリプトにはフォームが必要です。var updateがURLに渡された場合、フォームはユーザーのユーザー名と電子メールアドレスを要求するだけです。更新が渡されない場合は、ユーザー名、電子メールアドレス、および電子メールで送信されたIDコードを要求されます。また、新しいパスワードを要求します(もちろん2回)。
ユーザーの新しいパスワードを確認するには、ユーザー名、メールアドレス、IDコードがすべて一致していること、リクエストの有効期限が切れていないこと、2つの新しいパスワードが一致していることを確認します。成功した場合は、ユーザーのパスワードを新しいパスワードに変更し、ユーザーテーブルからパスワードリセットフィールドをクリアします。また、必ずユーザーをログアウト/ログイン関連のCookieをクリアして、ユーザーをログインページにリダイレクトしてください。
基本的に、new_passwd_idフィールドは、パスワードリセットページでのみ機能するパスワードです。
1つの潜在的な改善:電子メールから<username>を削除できます。「誰かがこのメールアドレスのアカウントのパスワードのリセットを要求しました...」したがって、ユーザー名を、メールが傍受された場合にユーザーだけが知っているものにします。誰かがアカウントを攻撃している場合、彼らはすでにユーザー名を知っているので、私はそのように始めませんでした。この追加されたあいまいさは、悪意のある誰かが電子メールを傍受した場合に、man-in-the-middle攻撃の機会を阻止します。
あなたの質問に関して:
ランダムな文字列の生成:極端にランダムである必要はありません。任意のGUIDジェネレーターまたはmd5(concat(salt、current_timestamp()))で十分です。ここで、saltは、タイムスタンプアカウントが作成されたようなユーザーレコード上のものです。それはユーザーが見ることができないものでなければなりません。
タイマー:はい、データベースを正常に保つためだけにこれが必要です。本当に必要なのは1週間以内ですが、電子メールの遅延がどのくらい続くかわからないため、少なくとも2日は必要です。
IPアドレス:電子メールは数日遅れる可能性があるため、IPアドレスはログ記録にのみ役立ち、検証には役立ちません。ログに記録する場合は記録します。それ以外の場合は必要ありません。
画面のリセット:上記を参照してください。
それをカバーすることを願っています。幸運を。