3

ここでナンスの生成と PHP に関するさまざまな質問を調べてきましたが、ナンスの「一度」の側面を管理する詳細についての議論は見つかりませんでした。

これが私の状況です。

Web サービスにアクセスする必要がある PHP がいくつかあり、Web サービスへの要求では、PHP が nonce を生成して要求に署名する必要があります (つまり、web サービスから nonce を要求していません)。その部分は簡単です。

複数のセッションが進行している可能性がある場合にナンスの再利用を防ぐための良い解決策に苦労しています。

そう考えると、私にできることは3つあります。

1 つは、nonce/timestamp のペアをデータベースに保存し、データベースで既存の nonce をチェックし、古い nonce を失効させるなどのロジックを実装することです。これには、スレッド セーフのためにTRANSACTIONorも必要です。LOCK TABLEうん。

2 つ目は、ノンスを APC のストアに保存し (私の場合は memcached を使用できません)、TTL に有効期限を処理させることです。この場合、スレッドセーフにはロジックをラップする必要がありますか、またはsem_acquire()本当にスレッドセーフですか? これに関する私の主な関心事は、キャッシュがいっぱいであるために実際に失敗した場合に状況を処理する方法です。sem_release()apc_add()apc_add()apc_store()

3 つ目は、APC の代わりに Cache_Lite を使用することです。

他のオプションはありますか?私が知る限り、OpenID は Cache_Lite でナンスを管理するので、これが最善の解決策だと思いますが、コミットする前にすべてのオプションを確認したいと考えています。

ありがとう。

4

1 に答える 1

7

1 つは、nonce/timestamp のペアをデータベースに保存し、データベースで既存の nonce をチェックし、古い nonce を期限切れにするなどのロジックを実装することです。これには、スレッド セーフのための TRANSACTION または LOCK TABLE も必要です。うん。

これは、テーブルをロックしなくても実行できます。使用しているデータ ストアがACID 準拠である限り、面倒な作業はすべて自動的に行われます。これは、MySQL を使用している場合は InnoDB テーブルを使用することを意味します。

nonce、作成時間、最大有効期間、およびそれがいつ消費されたかのフィールドを含むテーブルを作成します。nonce を主キーまたは一意にします。ノンスを割り当てるには、テーブルに挿入します。重複キー エラーが発生した場合 (またはトランザクションを使用してデッドロックや同様の問題が発生した場合)、それをキャッチして新しいナンスを生成します。

のような適切な乱数発生器openssl_random_pseudo_bytesを使用していて、ナンスに十分なバイトを収集している場合、衝突の可能性は最初は非常に小さいです。

ノンスを消費済みとしてマークする必要がある場合は、ノンス行に対して単純な UPDATE を実行し、消費された列が null であることも必要とします。更新は、変更された行数 (またはトランザクションを使用している場合はデッドロック) を返します。変更された行数がゼロの場合、またはデッドロックが発生した場合は、他の何かがすでに nonce を消費済みとしてマークしているため、適切なエラーをユーザーに返すことができます。

適切なデータベース エンジンは、この種のナンセンスを処理するように設計されていることを忘れないでください。車輪を再発明しないでください。

于 2011-03-09T18:03:47.513 に答える