私は自分のアプリケーションに同じアプローチを使用することを考えています。一般的には安全だと思いますが、キャッシュの一貫性の問題に取り組むには特別な注意が必要です。
Django が通常動作する方法は、リクエストが受信されると、Session テーブルに対してクエリが実行され、リクエストから Cookie に関連付けられたセッションが検索されます。次に、 にアクセスrequest.user
すると、User テーブルに対してクエリが実行され、特定のセッションのユーザーが検索されます (存在する場合、Django は匿名セッションをサポートしているため)。そのため、デフォルトでは、Django は各リクエストをユーザーに関連付けるために 2 つのクエリを必要とし、コストがかかります。
Django セッションの優れた点は、モデル クラスを拡張せずにキー、値ストアとして使用できることです (たとえば、フィールドを追加して拡張するのが難しい User クラスとは異なります)。request.session['email'] = user.email
したがって、たとえば、セッションに追加のデータを保存することができます。これはある意味では安全であり、request.session
辞書から読み取ったものは確かにそこに置いたものであり、クライアントはこれらの値を変更する方法がありません。したがって、実際にこの手法を使用して、 User テーブルへのクエリを回避できます。
セッション テーブルへのクエリを回避するには、セッション キャッシングを有効にする必要があります (または、セッション データを を使用してクライアント Cookie に格納しますdjango.contrib.sessions.backends.signed_cookies
。このような Cookie はクライアントによる変更に対して暗号で保護されているため、安全です)。
キャッシュを有効にすると、リクエストをユーザー データに関連付けるために必要なクエリは 0 になります。しかし、問題はキャッシュの一貫性です。ライト スルー オプション ( django.core.cache.backends.locmem.LocMemCache
with django.contrib.sessions.backends.cached_db
) を指定してローカル インメモリ キャッシュを使用する場合、セッション データは変更のたびに DB に書き込まれますが、キャッシュに存在する場合は DB から読み取られません。これにより、複数の Django プロセスがある場合に問題が発生します。1 つのプロセスがセッションを変更した場合 (変更などsession['email']
)、他のプロセスはキャッシュされた古い値を引き続き使用できます。
共有キャッシュ (Memcached バックエンド) を使用することで解決できます。これにより、1 つのプロセスによって行われた変更が他のすべてのプロセスに表示されることが保証されます。このようにして、Session テーブルへのクエリを Memcached バックエンドへのリクエストに置き換えます。これははるかに高速になるはずです。
セッション データをクライアント Cookie に保存すると、キャッシュの一貫性の問題も解決できます。Cookie の電子メール フィールドを変更すると、クライアントから送信される今後のすべてのリクエストに新しい電子メールが送信されます。クライアントは意図的に古い Cookie を送信することができますが、古い値がまだ保持されています。これが問題になるかどうかは、アプリケーションによって異なります。