リバースプロキシを使用してフォームをキャッシュし、古いフォームトークンを処理する方法


8

Form APIがフォームを生成するとき、フォームとともに非表示フィールドに渡され、返されることが期待されるトークンも生成します。そうであれば、フォームは処理されます。

レンダリングされたフォームが、たとえばVarnishによってキャッシュされる場合、このメカニズムは機能しません。フォームを送信した最初のユーザーがトークンを使用し、その後のフォームの使用の試みは拒否されます。

レンダリングされたフォームをキャッシュしている間、フォームを機能させ続けるにはどのような戦略がありますか?


あなたはこれについて確信を持っていますか?フォームとリバースプロキシを使用してサイトを構築しましたが、問題は発生していません。一般に、注意しなければならない唯一のことは、結果ページがキャッシュされないようにすることです。
アルフレッドアームストロング

それが私の問題を解決するので、私は間違っていることが証明されたいですが、そうです、確かに。:)詳細については、form_ {g、s} et_cache関数を確認してください。
Letharion 2013年

匿名ユーザーの場合、フォームのあるページを安全にキャッシュできると確信しています。非匿名ユーザーの場合、リバースプロキシはどのような場合でも問題があります。
アルフレッドアームストロング

2
(トークンは、ユーザーがIDを持っている場合にのみ生成されます。)
Alfred Armstrong

1
ああ、それは理にかなっています。残念ながら、この場合のユーザーは認証されます。おそらく、質問を書き直して、それを含める必要があります。
Letharion 2013年

回答:


5

私のサイトではBOAを使用していますが、デフォルトでは、BOAはフォーム送信のフロントエンドキャッシングをオンザフライで無効にするだけです。私の実際の経験を超えて、ニュージーランドポストがDrupal&Varnishをどのように扱うか、フォームトークンの問題について、1歳の人工的なクロスに行きました。神聖なジョン・ウェイン、それは本当にDrupalキャッシングの必読です。フォームの問題のみに注目:

パズルの最後のピースはCookieキャッシュバイパスアドバンスモジュールです。これは、ユーザーがサイトでPOSTフォーム(ログインフォームなど)を送信するたびに、特別なNO_CACHE Cookieを自動的に設定します。Varnishは、このCookieを検出したときに、ページキャッシュ(ESIキャッシュではなく)をバイパスするように構成されています。

XSRFプロダクションがform_alter(unset($ form ['#token']);)または($ form ['#token'] = FALSE;)で再取得されない場合は、フォームトークンを無効にすることもできます。

Acquia Drupalのパフォーマンスに関する記事では、DrupalモジュールのAuthcache公開されていますが、Authcacheのドキュメントを読むと、フォームのプレースホルダー(フォームをキャッシュしない)でキャッシュが機能します。

Authcacheは、カスタマイズされたコンテンツをインターセプトし、HTML内にプレースホルダーを設定しようとします。次に、ページが読み込まれた後、Ajaxコールバックを使用してカスタムデータを取得し、プレースホルダーに入力して、ページのHTMLを動的に更新します。

現在のAuthcacheプレースホルダー:フォームトークン(ログインユーザーのみ、クロスサイトリクエストフォージェリ攻撃を防ぐために> Drupalが必要)

戦略は、フォーム以外をすべてキャッシュすることです。それでは、他のすべてに対処します。たぶんVarnishはまったく使用されていません、MemcacheとRedis?私の戦略は、BOAとその背後にあるウィザード(omega8.cc)を使用しているため、BOAが提供するものを使用することです。問題を解決する外部キャッシュがあるとは思いません。それらはすべてフォームをバイパスするようです。

やる部分キャッシュを前述のauthcacheで細かく微調整ビューとNZポストの記事で述べたとのようにパネルとWunderkrautで脳信託によって記述問題古いが、アドレス- 。

Drupal ESIモジュールを使用してください。ワニスは部分的にESIに準拠しています):

ESI(エッジサイドインクルード)は、認証済みユーザー向けの高性能キャッシュソリューションですが、匿名ユーザーにも役立ちます。

通常、認証されたユーザー向けにパーソナライズされたページ(「Manarthとしてログイン」と言うブロックなどのマイナーなパーソナライズでも)は、リバースプロキシ(Drupalの100倍の速度で簡単に実行できる)がページをキャッシュするのを防ぎます。あるユーザーを対象としたものは、別のユーザーに表示される可能性があります。

それがもっと役立つことを願っています。


コードをざっと見てみると、ESIモジュールはフォームの検証に関して何もしていません。トークンの取り扱いについての言及はなく、興味深い形式の変更もありません。認証を必要とするフォームをワニスにキャッシュしていない可能性がありますが、それがこの問題を見たことがない理由ですか?
Letharion 2013年

これがまさに何が起こっているのかがわかります。BOAは、フォームのオンザフライでフロントエンドキャッシュをバイパスします(以前の私の不完全な/間違った回答については申し訳ありません)。ESIは、「すべてをキャッシュするが」の戦略の重要な部分ですが、直接解決しない場合でも、私の答えになりました。
トム・

そのNZの投稿記事は本当に本当に興味深いものでした。しかし、私が知ることができるように、それは「XSRF保護が重要ではないことが確かである場合... Drupalがフォームトークンを無効にするメカニズムを提供する」というトークンの問題にのみ対処します。これは、私の場合。
Letharion 2013年

ただし、役立つ情報がたくさんあり、他の人も問題にそれを適用できるでしょう。+1、残りわずか1時間なので、報奨金も認識できます。:)
Letharion 2013年

0

考えられる解決策の1つは$form[‘#token’] = FALSE;、とともにトークンをすべて無効にし、実際にコメントを投稿する代わりに送信コールバックをオーバーライドし、トークンを使用して元のフォームを再生成し、ユーザーに投稿の確認を求めることです。

ユーザーがECMAScriptをサポートしている場合、新しいフォームトークンのフォーム生成を公開し、関連するフォームをに挿入するサービスリソースを提供することで、ユーザーエクスペリエンスを向上させることができますform_cache。次に、ユーザーがフォームにフォーカスし、送信を希望するようになるとすぐに、送信ボタンを無効にし、新しいトークンをフェッチして、既にレンダリングされているフォームに挿入し、送信ボタンを再度有効にします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.