4


3

誰かがHTMLフォームを編集していてセッションがタイムアウトしたとしたら、ユーザーがフォームに入力したコンテンツを失うことなくDjangoにその個人を再認証させるにはどうすればよいでしょうか。

スニペット Django Snippets:サイト全体でログインを要求するは、サイト全体の認証を行う方法を示唆していますが、文字列のGETコンポーネントが失われることを期待しています(つまり、 request.pathはそれを含みません)、そして間違いなくPOSTデータを失います。

どうやってPOSTやGETをこれらの不便なタイムアウトを超えて保存することができますか。 私は巧妙なWebサイトがこれを賢く扱う傾向があることに気付きました、そして私はDjangoでそれを実行できることを望みます(他の人と同じように、私も想像します!)。

考えていただければ幸いです。 ありがとうございました。

4 Answer


3


2つの提案があります。

リダイレクト/ミドルウェア

ログイン要件を処理するためにすでにミドルウェアを使用しているので、このミドルウェアを変更することができます。 あるいは、ログインミドルウェアの後に呼び出される別のミドルウェアクラスを作成します。 これらのアイディアは絡み合っているので、既存のアイディアを修正することはより理にかなっているかもしれません。

  1. ログインしていない場合は、ミドルウェアでGETおよびPOSTデータを取得し、それをセッションに保存します。

  2. ユーザーが認証された場合は、#1に設定されている値を確認してください。 存在する場合は、request.GETとrequest.POSTを修正して反映し、セッションデータを削除します。

私はこれがきれいに機能するはずだと思います、そして多くの人がそれが役に立つと思うでしょう。 それは djangosnippets.orgへの素晴らしい投稿になるでしょう。

Ajaxテクニック

フォームの処理がすでに整っている場合、これはあまり実用的ではありませんが、ユーザーエクスペリエンスを向上させることができます。 非同期でPOSTを実行すると、Javascriptハンドラは「ログインが必要」という応答コードを認識してから、ログインを要求するポップアップダイアログを表示する可能性があります。 完了すると、ユーザーはフォームを再送信できます。


2


`+ onsubmit +`ハンドラーをJS経由でセッションをチェックするすべてのフォームに追加し、続行する前にログインの使用を促す。 この方法では、ユーザーが再度ログインする前にフォーム送信が実際に行われることはありません。

また、ログインしたユーザーがセッション間で変わらないことを確認してください。


2


これはDjango特有のものではなく、HTTP(The Stateless)特有のものです…​ システムがPOST(元のPOSTからGETへの切り替え)を処理している間にRedirectを発行してデータを失う危険性がある場合は、データをどこかに保存し(db、memcachedなど)、それらを保存するキーを認証によって伝えます。 (または他の)プロセス。

最も簡単なのはCookieで、キーについては何も気にする必要がありません。 より難解だがより強固な(読みやすいCookie jarに対して)URLキーをリダイレクトすることと、要求から要求へと連続して中継すること(ほぼ10年前のソリューションにおけるSESSIONのように)。

認証(または他のプロセス)が終了すると、渡されたキーによってデータストアからデータ(およびプロセスが中断された)を選択できます(CookieまたはGETリクエスト変数から)。


0


セッションは一般的には好きではありませんが、認証済みのサイトですでに使用していると思いますので、上記の回答があなたのアプローチに合っているかもしれません。

セッションがなければ、私はダニエルズの答えに似たようなことをしたいと思います。 ミドルウェアで元のPOST / GETをキャッチしますが、投稿情報を含めるようにリダイレクトを変更します。

これはGETの方が簡単で、通常はログインURLのリダイレクトコンポーネントにエンコードされた完全なGETstringです。

POSTの場合は、小さいフォームではうまくいくが、大きいフォームではURLが長くなりすぎるgetメソッドに変換することができます。rePOSTを実行し、データをエンコードされたログインフォームにポストして1つのデータに格納します。隠されている(実際には.netビューステートのように)

リダイレクトはできないので、djangoでこれを行うのは難しいので、ミドルウェアを使用して手動でログインビューを呼び出し、そこからHttpResponseに書き込みます。 編集これをもう少し検討した後、明らかにdjangoのための魔法の管理者側は Jerry Strattonによって見つけられるように類似した何かが既に実装されています。

良い選択肢のように見えます。 試してみて、フィードバックします。