セッションの使いかたLink to this heading
Django は、匿名のセッションをフルサポートしています。このセッションフレームワークを使えば、任意のデータを、サイトの訪問者ごとに保存し、取得することができます。データはサーバー側に保存され、クッキーの送受信によって抽象化します。クッキーには、データそのものではなくセッション ID が書かれています ( クッキーベースのバックエンド を使用しない限り)。
セッションを有効にするLink to this heading
セッションは、 ミドルウェア の1つを使って実装されています。
セッションの機能を有効にするには、次のように設定を行います。
MIDDLEWARE設定を編集し'django.contrib.sessions.middleware.SessionMiddleware'を含むようにする。django-admin startprojectで作られるデフォルトのsettings.pyはSessionMiddlewareが有効化されています。
セッションを使いたくない場合は、 MIDDLEWARE 内の SessionMiddleware 行と INSTALLED_APPS 内の 'django.contrib.sessions' を削除しても構いません。これで、オーバーヘッドが少しだけ短縮されます。
セッションエンジンを設定するLink to this heading
デフォルトでは、Django はセッションを、(django.contrib.sessions.models.Session モデルを用いて) データベースに保存します。これは便利ですが、セットアップによってはセッションのデータを他の場所においたほうが高速化できる場合があります。そのため、Django はセッションデータをファイルシステムやキャッシュに保存するように設定することができます。
データベースを使ったセッションLink to this heading
データベースを使った (database-backed) セッションを使いたい場合には、設定ファイルの INSTALLED_APPS に 'django.contrib.sessions' を追加する必要があります。
一度インストールの設定をすれば、manage.py migrate を実行することで、セッションデータを保存する1つのデータベーステーブルをインストールできます。
キャッシュを使ったセッションLink to this heading
よいパフォーマンスを発揮するには、キャッシュを使ったセッションバックエンドを利用した方が良いかもしれません。
Django のキャッシュシステムを使ってセッションデータを保存するには、まず初めに、キャッシュの設定を済ませておく必要があります。詳しくは、 キャッシュのドキュメンテーション を読んでください。
設定ファイルの CACHES で複数のキャッシュを定義している場合、Django はデフォルトのキャッシュを使用します。他のキャッシュを使用するには、SESSION_CACHE_ALIAS を使用したいキャッシュの名前に変更します。
キャッシュの設定が完了したら、キャッシュへのデータの保管方法を、次の2つの選択肢から選ぶことができます。
SESSION_ENGINEを"django.contrib.sessions.backends.cache"に設定すると、シンプルなキャッシュセッションを保存します。セッションデータはキャッシュに直接保存されることになります。しかし、この場合、セッションデータが永続化されず、キャッシュがいっぱいになったりキャッシュサーバが再起動した際に、一度キャッシュされていたデータがクリアされてしまうことがあります。キャッシュデータを確実に永続化したい場合には、
SESSION_ENGINEを"django.contrib.sessions.backends.cached_db"に設定します。こちらは、書き込み透過な (write-through) キャッシュを使用します。つまり、キャッシュにデータが書き込まれるのと同時に、データベースにも同じデータが書き込まれます。セッションは、データがキャッシュ上から読み込めない時に限り、データベースからデータを読み込みます。
いずれのセッションのデータの保存も非常に高速ですが、シンプルなキャッシュを使用した方が、永続化の処理をしないので、より高速です。ほとんどのケースでは cached_db バックエンドでも十分高速ですが、パフォーマンスを最重視していて、セッションデータが時間経過で失われてもかまわない場合には、cache バックエンドを使用すると良いでしょう。
cached_db セッションバックエンドを使用する場合には、using database-backed sessions に書かれている手順にしたがって、設定を行ってください。
ファイルを使ったセッションLink to this heading
ファイルを使ったセッションを使用するには、SESSION_ENGINE を "django.contrib.sessions.backends.file" に設定します。
Django がセッションファイルを保存する場所を設定したい場合には、SESSION_FILE_PATH を設定します (出力先のデフォルト値は、tempfile.gettempdir()、普通は /tmp になっています。)。Web サーバが設定した場所の読み書きの権限を持っていることを確認しておいてください。
ビューでセッションを使うLink to this heading
SessionMiddleware を有効にすれば、それぞれの HttpRequest オブジェクト――Django のビュー関数に渡される最初の引数――は、ディクショナリライクなオブジェクトの session 属性を持つようになります。
この request.session には、ビューの好きな場所で、何度でも、読み書きを行うことができます。
- class backends.base.SessionBaseLink to this definition
このオブジェクトは、すべてのセッションオブジェクトのベースクラスとなっているので、以下に挙げるような基本的なディクショナリのメソッドを持っています。
- __getitem__(key)Link to this definition
例:
fav_color = request.session['fav_color']
- __setitem__(key, value)Link to this definition
例:
request.session['fav_color'] = 'blue'
- __delitem__(key)Link to this definition
例:
del request.session['fav_color']与えられたkeyがセッション内にない場合には、KeyError例外を起こします。
- __contains__(key)Link to this definition
例:
'fav_color' in request.session
- get(key, default=None)Link to this definition
例:
fav_color = request.session.get('fav_color', 'red')
- pop(key, default=__not_given)Link to this definition
例:
fav_color = request.session.pop('fav_color', 'blue')
- keys()Link to this definition
- items()Link to this definition
- setdefault()Link to this definition
- clear()Link to this definition
また、次のようなメソッドも利用できます。
- flush()Link to this definition
セッションから現在のセッションデータを削除し、セッションクッキーを削除します。このメソッドは、前回のセッションデータがユーザのブラウザから再びアクセスされないようにするためなどに使います (たとえば、
django.contrib.auth.logout()がこの関数を呼びます)。
- set_test_cookie()Link to this definition
ユーザのブラウザがクッキーをサポートしているかどうか判定するために、テスト用のクッキーをセットします。クッキーの動作原理により、ユーザが次のページへのリクエストを行わないとこのテストは行えません。詳しい情報については、下の Setting test cookies を読んでください。
- test_cookie_worked()Link to this definition
ユーザのブラウザがテストクッキーを正しく保存したかどうかに応じて、
TrueまたはFalseを返します。クッキーの動作原理により、あらかじめ別のページのリクエストとしてset_test_cookie()を呼び出しておく必要があります。詳しい情報については、下の Setting test cookies を読んでください。
- delete_test_cookie()Link to this definition
テストクッキーを削除します。クッキーをきれいにしておくために使ってください。
- set_expiry(value)Link to this definition
セッションの有効期限を設定します。以下に挙げるようなさまざまな値を与えることができます。
もし
valueが整数なら、与えられた秒数だけ活動がなかった時にセッションを破棄します。たとえば、request.session.set_expiry(300)と呼び出せば、5分後にセッションを破棄するように設定できます。もし
valueがdatetimeまたはtimedeltaオブジェクトならば、指定された日時に破棄されます。datetimeとtimedeltaの値がシリアライズできるのは、PickleSerializerを使っている場合のみであることに注意してください。もし
valueが0ならば、ユーザのセッションクッキーは、ユーザがウェブブラウザを閉じた時に破棄されます。もし
valueがNoneならば、セッションはグローバルなセッション有効期限ポリシーにしたがって扱われます。
セッションの読み込みを行っても、有効期限は延長されません。セッションの有効期限は、セッションが最後に*修正された*時点を基に計算されます。
- get_expiry_age()Link to this definition
このセッションの有効期限までの残りの秒数を返します。カスタムの有効期限を持たない (または、ブラウザを閉じた時とセットした) セッションの場合、この値は
SESSION_COOKIE_AGEと等しいです。この関数は 2 つの省略可能なキーワード引数を取ることができます。
modification: セッションを最後に修正した時刻をdatetimeオブジェクトとして与える。デフォルトは現在の時刻。expiry: セッションの有効期限の情報をdatetimeオブジェクト、int(秒数で)、またはNoneとして与えます。デフォルトの値は、もしあれば、セッションに保存されているset_expiry()で得られる値、なければNoneです。
- get_expiry_date()Link to this definition
このセッションが破棄される日付を返します。カスタムの有効期限を持たない (または、ブラウザを閉じた時とセットした) セッションに対しては、現在時刻から
SESSION_COOKIE_AGEの秒数までの日付に等しいです。この関数は、
get_expiry_age()と同じキーワード引数を取ることができます。
- get_expire_at_browser_close()Link to this definition
ユーザのセッションクッキーがユーザのブラウザが閉じた時に破棄されるかどうかに応じて、
TrueまたはFalseを返します。
- clear_expired()Link to this definition
保存されているセッションから、有効期限が切れているものを削除します。このクラスメソッドは、
clearsessionsから呼び出されます。
- cycle_key()Link to this definition
現在のセッションデータを保持したまま、新しいセッションキーを作成します。
django.contrib.auth.login()は、このメソッドを呼び出すことで、過去のセッションを継続できるようにしています。
セッションのシリアライズLink to this heading
デフォルトでは、Django はセッションデータを JSON を用いてシリアライズします。設定ファイルの SESSION_SERIALIZER に設定すれば、セッションをシリアライズするフォーマットをカスカムできます。自作のシリアライザを書く に書いた注意書きの通り、JSON によるシリアライズを強く推奨します。*クッキーバックエンドを利用している場合は特にです。
たとえば、セッションデータをシリアライズするために pickle を使用していた場合の、こんな攻撃のシナリオを考えてみましょう。あなたは 署名したクッキーセッションバックエンド を使用していて、SECRET_KEY が攻撃者に知られてしまっていたとします (もちろん、これは Django にキーが流出する脆弱性が内在しているというわけではありません)。この時、攻撃者は、セッションに任意の文字列を挿入することができてしまい、このセッションをアンピックすると、サーバ上で任意のコードが実行されてしまいます。このような攻撃は、インターネット上のどこからでも簡単にできてしまいます。クッキーセッションストレージは、クッキーに保存されているデータが勝手に書き換えられないようにクッキーに署名をしていますが、SECRET_KEY が流出するだけで、リモートからコードを実行されてしまう脆弱性が生まれてしまうのです。
バンドルされているシリアライザLink to this heading
- class serializers.JSONSerializerLink to this definition
django.core.signingの JSON シリアライザのラッパーです。基本的なデータ型だけがシリアライズ可能です。また、JSON は文字列のキーしかサポートしていないので、
request.sessionに文字列以外のキーを使用してしまうと、次のように期待通りに動いてくれません。>>> # initial assignment >>> request.session[0] = 'bar' >>> # subsequent requests following serialization & deserialization >>> # of session data >>> request.session[0] # KeyError >>> request.session['0'] 'bar'Similarly, data that can't be encoded in JSON, such as non-UTF8 bytes like
'\xd9'(which raisesUnicodeDecodeError), can't be stored.JSON によるシリアライズの制限について詳しくは、自作のシリアライザを書く セクションを読んでください。
- class serializers.PickleSerializerLink to this definition
任意の Python オブジェクトをサポートしますが、上に書いた理由により、このシリアライザを使用すると、攻撃者に
SECRET_KEYが知られた場合に、リモートからコードを実行される脆弱性を生んでしまいます。
自作のシリアライザを書くLink to this heading
Note that unlike PickleSerializer,
the JSONSerializer cannot handle
arbitrary Python data types. As is often the case, there is a trade-off between
convenience and security. If you wish to store more advanced data types
including datetime and Decimal in JSON backed sessions, you will need
to write a custom serializer (or convert such values to a JSON serializable
object before storing them in request.session). While serializing these
values is fairly straightforward
(DjangoJSONEncoder may be helpful),
writing a decoder that can reliably get back the same thing that you put in is
more fragile. For example, you run the risk of returning a datetime that
was actually a string that just happened to be in the same format chosen for
datetimes).
シリアライザのクラスは、必ず次の2つのメソッドを実装しなければなりません。セッションデータのディクショナリをシリアライズする dumps(self, obj) と、それをデシリアライズする loads(self, data) の2つです。
セッションオブジェクトのガイドラインLink to this heading
Python の普通の文字列を、
request.sessionにおけるディクショナリのキーとして使うこと。これは慣習のためというよりも、確実で高速にするためのルールです。セッションのディクショナリのキーで、アンダースコアで始まるキーは、Django が内部で使用するために予約されているものと考えること。
request.sessionを新しいオブジェクトで上書きせず、その属性にアクセスしたり、値をセットしたりしないこと。Python のディクショナリのように扱うこと。
例Link to this heading
次の簡単なビューは、ユーザがコメントを投稿した後で、has_commented 変数を True に設定します。こうすることで、同じユーザが2回以上コメントできないようにすることができます。
def post_comment(request, new_comment):
if request.session.get('has_commented', False):
return HttpResponse("You've already commented.")
c = comments.Comment(comment=new_comment)
c.save()
request.session['has_commented'] = True
return HttpResponse('Thanks for your comment!')
次の次の簡単なビューでは、サイトの「メンバー (member)」にログインする手続きを行います。
def login(request):
m = Member.objects.get(username=request.POST['username'])
if m.password == request.POST['password']:
request.session['member_id'] = m.id
return HttpResponse("You're logged in.")
else:
return HttpResponse("Your username and password didn't match.")
そして、次の例では、上の login() に対応するメンバーのログアウト処理を行います。
def logout(request):
try:
del request.session['member_id']
except KeyError:
pass
return HttpResponse("You're logged out.")
ふつう実際に使われる django.contrib.auth.logout() 関数では、データの意図しない漏洩を防ぐために、この例より少し複雑な処理、request.session の flush() メソッドを呼び出すなどの処理を行っています。ここで挙げた例は、単にセッションオブジェクトの振る舞いをデモンストレーションすることが目的なので、完全ではない logout() を実装しました。
ビューの外でセッションを使うLink to this heading
次のようにして、ビューの外からセッションデータを操作する API が利用可能です。
>>> from django.contrib.sessions.backends.db import SessionStore
>>> s = SessionStore()
>>> # stored as seconds since epoch since datetimes are not serializable in JSON.
>>> s['last_login'] = 1376587691
>>> s.create()
>>> s.session_key
'2b1189a188b44ad18c35e113ac6ceead'
>>> s = SessionStore(session_key='2b1189a188b44ad18c35e113ac6ceead')
>>> s['last_login']
1376587691
SessionStore.create() is designed to create a new session (i.e. one not
loaded from the session store and with session_key=None). save() is
designed to save an existing session (i.e. one loaded from the session store).
Calling save() on a new session may also work but has a small chance of
generating a session_key that collides with an existing one. create()
calls save() and loops until an unused session_key is generated.
django.contrib.sessions.backends.db バックエンドを使用している場合、各セッションは単なる Django のモデルになっていて、Session モデルは django/contrib/sessions/models.py で定義されています。普通のモデルにすぎないので、普通の Django データベース API からセッションにアクセスできます。
>>> from django.contrib.sessions.models import Session
>>> s = Session.objects.get(pk='2b1189a188b44ad18c35e113ac6ceead')
>>> s.expire_date
datetime.datetime(2005, 8, 20, 13, 35, 12)
セッションのディクショナリを取得するには、get_decoded() を呼ばなければならないことに注意してください。これが必要なのは、ディクショナリがエンコードされたフォーマットで保存されているためです。
>>> s.session_data
'KGRwMQpTJ19hdXRoX3VzZXJfaWQnCnAyCkkxCnMuMTExY2ZjODI2Yj...'
>>> s.get_decoded()
{'user_id': 42}
セッションが保存されるタイミングLink to this heading
デフォルトでは、Django がセッションデータベースへデータを保存するのは、セッションが修正された時だけ、つまり、ディクショナリ直下の値が代入または削除された時だけです。
# Session is modified.
request.session['foo'] = 'bar'
# Session is modified.
del request.session['foo']
# Session is modified.
request.session['foo'] = {}
# Gotcha: Session is NOT modified, because this alters
# request.session['foo'] instead of request.session.
request.session['foo']['bar'] = 'baz'
上の例の場合、セッションオブジェクトに修正したことを明示的に伝えるためには、modified 属性を設定すれば良いです。
request.session.modified = True
このデフォルトの動作を変更するには、設定ファイルの SESSION_SAVE_EVERY_REQUEST を True に設定します。True に設定すると、Django は1リクエストごとに、セッションをデータベースに保存してくれるようになります。
セッションクッキーが送信されるのは、セッションの作成及び修正時のみであることに注意してください。SESSION_SAVE_EVERY_REQUEST を True に設定すると、各リクエストごとにセッションクッキーが送信されるようになります。
同時に、セッションクッキーの expires 部分も、セッションクッキーが送信されるごとに更新されます。
レスポンスステータスコードが 500 の時には、セッションは保存されません。
ブラウザ起動中のみ有効なセッション vs. 永続的なセッションLink to this heading
SESSION_EXPIRE_AT_BROWSER_CLOSE 設定を使うと、セッションフレームワークが、ブラウザ起動中のみ有効なセッションと永続的なセッションのどちらを使うか設定できます。
デフォルトでは、SESSION_EXPIRE_AT_BROWSER_CLOSE は False にセットされていて、セッションクッキーは SESSION_COOKIE_AGE の期間ユーザのブラウザに保持されます。これにより、ユーザはブラウザを開くたびにログインし直さずに済みます。
SESSION_EXPIRE_AT_BROWSER_CLOSE を True に設定すると、Django はブラウザ起動中のみ有効なクッキーを使用します。このクッキーは、ブラウザを閉じた瞬間に破棄されます。ユーザがブラウザを開くたびにログインするようにしたい場合には、この設定を利用してください。
この設定はグローバルなデフォルトですが、1セッションごとのレベルで設定を上書きすることができます。その場合には、上の using sessions in views で書いたようにして、request.session の set_expiry() メソッドを呼び出してください。
セッションストアのクリアLink to this heading
ユーザがウェブサイトで新しいセッションを作成した時、セッションデータはセッションストアに溜め込まれます。データベースのバックエンドを使っている場合には、django_session データベーステーブルが増大し、ファイルバックエンドを使っている場合には、一時ディレクトリのファイル数が増えてゆくでしょう。
この問題を理解するには、データベースバックエンドで起きていることを考えてみてください。ユーザがログインすると、Django は django_session データベースのテーブルに1行を追加します。Django はセッションのデータが変更されるたびに、この行を更新します。ユーザが手動でログアウトすると、Django はこの行を削除します。しかし、ユーザがログアウト*しなかった*場合には、この行は決して削除されません。同様のプロセスが、ファイルバックエンドの場合にも発生します。
Django は、有効期限の切れたセッションを自動的に削除する機能を提供*しません*。したがって、定期的に有効期限の切れたセッションを削除する仕事は、開発者の手に委ねられています。Django はこの目的のために、クリーンナップ用の管理コマンド clearsessions を用意しています。たとえば、cron の毎日のジョブに追加するなどの方法で、定期的にこのコマンドを実行することが推奨されています。
キャッシュバックエンドの場合はこの問題が発生しないことに注意してください。キャッシュの場合、不要なデータは自動的に削除されるようになっているからです。しかし、クッキーバックエンドの場合はそうではありません。セッションデータはユーザのブラウザに保存されるからです。
設定Link to this heading
以下の Django の設定 を使うと、セッションの振る舞いをコントロールすることができます。
セッションのセキュリティLink to this heading
サイトのサブドメインからは、クライアントに対して、ドメイン全体に対するクッキーを設定することができます。信頼できるユーザに管理されていないサブドメインから送られたクッキーを許可している場合、この方法で session fixation 攻撃が可能になってしまいます。
たとえば、攻撃者が good.example.com にログインして、攻撃者のアカウントに対する有効なセッションを取得したとしましょう。この攻撃者が bad.example.com を自由に使えた場合、サブドメインからは *.example.com に対してクッキーを設定できるので、先ほど取得したセッションを利用して、攻撃者のセッションキーをターゲットの利用者に送信できてしまいます。次にこの利用者が good.example.com を訪問すると、この利用者は攻撃者のアカウントにログインすることになり、そのことに気付かずに大切な個人のデータ (たとえば、クレジットカード情報など) を攻撃者のアカウントに入力してしまう恐れがあります。
もう一つ考えられる攻撃は、good.example.com というサイトが SESSION_COOKIE_DOMAIN を ".example.com" に設定していた場合に、そのサイトのセッションクッキーが bad.example.com に送信されてしまう、というものです。
技術的な詳細Link to this heading
セッションのディクショナリは、
JSONSerializerを使用している場合にはjsonでシリアライズできるどんな値でも、PickleSerializerを使用している場合には pickle でシリアライズできるどんな Python オブジェクトでも、保存することができます。セッションデータは、データベースの
django_sessionという名前のテーブルに保存されます。Django は必要なときにだけクッキーを送信します。新しくセッションデータを設定しなければ、Django はセッションクッキーを送信しません。
SessionStore オブジェクトLink to this heading
Django が内部でセッションを操作する時は、対応するセッションエンジンの session store オブジェクトを使用します。慣習により、session store オブジェクトは SessionStore と名付けられていて、SESSION_ENGINE で指定したモジュール内に置かれています。
Django で利用可能なすべての SessionStore クラスは、SessionBase を継承していて、以下のデータを操作するメソッドを実装しています。
exists()create()save()delete()load()
独自のセッションエンジンを作ったり、既存のものをカスタマイズするには、SessionBase か既存の SessionStore クラスを継承した新しいクラスを作る必要があるでしょう。
大部分のセッションエンジンでは、拡張は簡単にできますが、データベースを使ったセッションエンジンの場合は、一般に少し手を加える必要があります (詳しくは次のセクションを読んでください)。
データベースを使ったセッションを拡張するLink to this heading
Django に含まれるデータベースを使ったセッションエンジン (具体的に言えば、db と cached_db) をカスタマイズするには、AbstractBaseSession とともに SessionStore クラスを継承する必要があるかもしれません。
AbstractBaseSession と BaseSessionManager は、INSTALLED_APPS に django.contrib.sessions を追加しなくても、django.contrib.sessions.base_session からインポートすることができます。
- class base_session.AbstractBaseSessionLink to this definition
-
ベースとなる抽象的なセッションのモデルです。
- session_keyLink to this definition
プライマリーキーです。フィールド自体は40文字までの文字列を格納できますが、現在の実装では、32文字の文字列 (数字と小文字のASCII文字のランダムな列) を生成します。
- session_dataLink to this definition
エンコード・シリアライズされた、セッションディクショナリーを含む文字列です。
- expire_dateLink to this definition
セッションの有効期限を表す datetime オブジェクトです。
有効期限が切れたセッションをユーザが利用することはできませんが、
clearsessions管理コマンドを実行するまでは、ふつうはデータベースに保存されています。
- classmethod get_session_store_class()Link to this definition
セッションモデルで使用するセッションストアクラスを返します。
- get_decoded()Link to this definition
デコードしたセッションデータを返します。
デコードは、セッションストアのクラスで実行されます。
BaseSessionManager のサブクラスを作ることで、モデルマネージャをカスタマイズすることもできます。
- class base_session.BaseSessionManagerLink to this definition
-
- encode(session_dict)Link to this definition
与えられたセッションディクショナリを、シリアライズ・エンコードした文字列として返します。
エンコードは、モデルクラスに関連付けられたセッションストアのクラスで実行されます。
- save(session_key, session_dict, expire_date)Link to this definition
与えられたセッションキーに対するセッションデータを保存します。データが空の場合には、セッションを削除します。
SessionStore クラスのカスタマイズは、以下に挙げるメソッドやプロパティをオーバーライドすることで行えます。
- class backends.db.SessionStoreLink to this definition
データベースを使ったセッションストアを実装しています。
- classmethod get_model_class()Link to this definition
-
カスタマイズしたセッションモデルを返す必要がある場合には、このメソッドをオーバーライドします。
- create_model_instance(data)Link to this definition
-
現在のセッションの状態を表す、セッションモデルオブジェクトの新しいインスタンスを返します。
このメソッドをオーバーライドすると、セッションモデルのデータをデータベースへ保存する前に修正することができます。
- class backends.cached_db.SessionStoreLink to this definition
キャッシュデータベースを使ったセッションストアを実装しています。
- cache_key_prefixLink to this definition
-
キャッシュのキー文字列を作るためにセッションキーに追加するプリフィックスです。
カスタマイズ例Link to this heading
The example below shows a custom database-backed session engine that includes an additional database column to store an account ID (thus providing an option to query the database for all active sessions for an account):
from django.contrib.sessions.backends.db import SessionStore as DBStore
from django.contrib.sessions.base_session import AbstractBaseSession
from django.db import models
class CustomSession(AbstractBaseSession):
account_id = models.IntegerField(null=True, db_index=True)
@classmethod
def get_session_store_class(cls):
return SessionStore
class SessionStore(DBStore):
@classmethod
def get_model_class(cls):
return CustomSession
def create_model_instance(self, data):
obj = super(SessionStore, self).create_model_instance(data)
try:
account_id = int(data.get('_auth_user_id'))
except (ValueError, TypeError):
account_id = None
obj.account_id = account_id
return obj
If you are migrating from the Django's built-in cached_db session store to
a custom one based on cached_db, you should override the cache key prefix
in order to prevent a namespace clash:
class SessionStore(CachedDBStore):
cache_key_prefix = 'mysessions.custom_cached_db_backend'
# ...
Session IDs in URLsLink to this heading
The Django sessions framework is entirely, and solely, cookie-based. It does not fall back to putting session IDs in URLs as a last resort, as PHP does. This is an intentional design decision. Not only does that behavior make URLs ugly, it makes your site vulnerable to session-ID theft via the "Referer" header.