1

Google App Engine で使用している User モデルのパスワード リセット トークンを生成したいと考えています。どうやら GAE で Django を簡単に使用することは許可されていないため、トークンを生成するための Django メソッドの生のコードは次のとおりです。

def _make_token_with_timestamp(self, user, timestamp):
    # timestamp is number of days since 2001-1-1.  Converted to
    # base 36, this gives us a 3 digit string until about 2121
    ts_b36 = int_to_base36(timestamp)

    # By hashing on the internal state of the user and using state
    # that is sure to change (the password salt will change as soon as
    # the password is set, at least for current Django auth, and
    # last_login will also change), we produce a hash that will be
    # invalid as soon as it is used.
    # We limit the hash to 20 chars to keep URL short
    key_salt = "django.contrib.auth.tokens.PasswordResetTokenGenerator"

    # Ensure results are consistent across DB backends
    login_timestamp = user.last_login.replace(microsecond=0, tzinfo=None)

    value = (unicode(user.id) + user.password +
            unicode(login_timestamp) + unicode(timestamp))
    hash = salted_hmac(key_salt, value).hexdigest()[::2]
    return "%s-%s" % (ts_b36, hash)

Python は私の専門言語ではないので、上記のようなカスタム メソッドを作成するのに助けが必要です。いくつか質問があります。まず、タイムスタンプの目的は何ですか? また、Django には独自の User システムがありますが、私は独自の単純なカスタム User モデルを使用しています。上記のコードのどの部分を保持する必要がありますか? また、どの部分を削除できますか?

4

1 に答える 1

1

-check_tokenメソッドは次のようになります。

def check_token(self, user, token):
    """
    Check that a password reset token is correct for a given user.
    """
    # Parse the token
    try:
        ts_b36, hash = token.split("-")
    except ValueError:
        return False

    try:
        ts = base36_to_int(ts_b36)
    except ValueError:
        return False

    # Check that the timestamp/uid has not been tampered with
    if not constant_time_compare(self._make_token_with_timestamp(user, ts), token):
        return False

    # Check the timestamp is within limit
    if (self._num_days(self._today()) - ts) > settings.PASSWORD_RESET_TIMEOUT_DAYS:
        return False

    return True
  • 最初に、トークンのタイムスタンプ部分が整数に変換されます
  • 次に、そのタイムスタンプを使用して新しいトークンが生成され、古いトークンと比較されます。
    トークンを生成するとき、最後のログインのタイムスタンプは、ハッシュの計算に使用されるパラメーターの 1 つです。これは、ユーザーがログインした後、古いトークンが無効になることを意味します。これは、パスワード リセット トークンにとって理にかなっています。
  • 最後に、トークンが既にタイムアウトしていないかどうかを確認するためにチェックが実行されます。

これはかなり単純なプロセスであり、かなり安全でもあります。リセット システムを使用してアカウントに侵入したい場合は、ハッシュを計算するために、ユーザーのパスワードと最終ログインのタイムスタンプを知る必要があります。そして、それがアカウントに侵入する必要がないことを知っていれば...

したがって、そのようなシステムを作成したい場合は、ハストを生成するときに推測しにくいパラメーターを使用することが重要です。もちろん、適切なソルト付きハッシュ関数を使用することも重要です。Djangoは sha1を使用しますが、他のhashlibダイジェストを使用することはもちろん簡単に可能です。

もう 1 つの方法は、ランダムなパスワード リセット トークンを生成してデータベースに保存することですが、ほとんどのユーザーにとってトークン列がおそらく空になるため、多くのスペースが無駄になる可能性があります。

于 2012-05-19T19:35:43.020 に答える