0

ユーザーがすべての質問に答える時間が限られている調査ページを作成しています。指定された時間は、秒を表す整数である @test.time_allowed としてモデルに保存されます。

タイマーをビューに表示し、タイマーが 0 になったときにコントローラー アクションを実行する、シンプルでユーザーが改ざんできない方法が必要です。どうすればこれを達成できますか?

私は比較的初心者なので、具体的な回答は本当に役に立ちます。ありがとうございました。

- -アップデート - -

@ブライアン:
タイミングがサーバー側で行われる場合、改ざん防止の方法があると思いますか?たとえば、あなたが提案したようにクライアント側にjavascriptタイマーがあるかもしれませんが、送信時にウィンドウの初期ロードの時間に対して送信時間をチェックすることはできませんか?

4

3 に答える 3

2

クライアントから返されたデータを完全に信頼することはできないため、サーバーは、最初に生成されたフォームのタイムスタンプが何であったかを何らかの方法で知る必要があります。これは、セッションまたはデータベースに変数を保存することで実行できますが、これには問題があります。代わりに、サーバーは、クライアントが変更していないことを確認するために、暗号化または署名された形式でタイムスタンプを配置できます。その後、サーバーは必要に応じて送信を拒否できます。クライアントでは、個別のロジックが UI 部分を処理し、ユーザーに制限時間に関するフィードバックを提供できますが、最終的には、これはサーバー処理と疎結合になっているだけです。

詳細:

サーバーは 2 つのフォーム フィールドを生成する必要があります。1 つtime = Time.now.to_iはフォームがいつ生成されたかを追跡するためのシステム タイムスタンプを持ち、もう 1 つは署名を持ちますDigest::MD5.hexdigest(time.to_s.concat('Some-secret-string-1234'))(ここでは、タイムスタンプ フォーム フィールドと署名フォーム フィールドに同じ時間値を使用していることに注意してください)。これは、クライアントによって変更されていないサーバー生成のタイムスタンプでフォームが送信されたことを検証します。

制限時間のある別のフォーム フィールドを送信することもできます。

クライアントでは、タイムスタンプを読み取り、setTimeout と時間制限を使用してカウントダウンを生成するか、フロント エンドで実行したいことを行います。

フォームが送信されたら、以前と同じ方法を使用して MD5 署名を再生成することにより、フォームで送信されたタイムスタンプを認証します。フォームから送信された署名と一致していることを確認してください。次に、タイムスタンプをタイムアウトに追加し、現在のサーバー時間よりも遅いことを確認します。もしそうなら、あなたの時間制限内で、あなたは有効な提出物を持っています。

ネットワークの遅延を考慮して、サーバーでのタイムアウトにはクライアントでのタイムアウトよりも少し余裕を持たせる必要があります。おそらく数秒です。サーバー要求が受信されると、タイマーが切れたように見えます。

require 'digest/md5'MD5 にアクセスするには、必ず追加してください。

このように MD5 署名を使用することは、クライアントがフォームのキー パラメータをステートレスな方法で変更していないことを確認する優れた方法です。トリックのバッグに加えるのに最適です。

幸運を!

于 2010-07-21T17:45:34.620 に答える
0

進行中のアンケートのモデルを作成し、after_create期限を に設定するフィルターを追加しTime.now + survey_durationます。モデルで回答の遅延送信を拒否するロジックを保持します。

于 2010-07-21T17:45:40.673 に答える
0

これを実装する 100% 改ざん防止の方法はありません。悪意のあるユーザーによってオフまたは操作される可能性がある JavaScript を使用してこれを行う必要があるためです。

ただし、これらの問題を気にしない場合は、ページにタイムアウトを設定して、秒数が経過した後にフォームを送信することができます。これを行うには、次のようなものが必要です。明らかtimeInMillisecondsに、サーバー側のテンプレートからページに生成する必要があります。

window.setTimeout(function() {
                     document.forms['survey_form'].submit();
                  },
                  timeInMilliseconds);
于 2010-07-21T06:08:48.320 に答える