Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?

Cowboy と Django でセッション情報を共有する

適材適所ということで、Cowboy を使いたい場面が出てきた。 ただし、基本的には Django を使って開発をする。特殊な部分だけ Erlang/OTP で実装された Cowboy を使う。

となると、Redis に格納したセッション情報を共有出来たりしないかと思い試してみた。

Django 側はとてもシンプルな、login 画面、と適当な index.html 一枚だけ。 明示的に /index/ なんて URL にしてみた。

Django のセッションを Redis に出すため django-redis-sessions をインストールする。

さらに、クッキー情報を共有するため SESSION_COOKIE_DOMAIN も設定してみた。

django の settings.py:

# セッション関連

SESSION_ENGINE = 'redis_sessions.session'

SESSION_REDIS_HOST = '127.0.0.1'
SESSION_REDIS_PORT = 6379
SESSION_REDIS_DB = 0
SESSION_REDIS_PREFIX = 'session'

# ログイン関連

LOGIN_URL='/download/login/'
LOGIN_REDIRECT_URL='/download/index/'

# クッキー関連

SESSION_COOKIE_DOMAIN='127.0.0.1'

redis に入ってるセッション情報:

$ redis-cli
redis 127.0.0.1:6379> KEYS *
1) "session:9510pia3jptvmycpnxcj337ox8zkp9xt"

Django と Cowboy はもちろん別で立っている

Django:127.0.0.1:8000
Cowboy:127.0.0.1:8080

cowboy 側に表示された HTTP ヘッダー:

{<<"cookie">>,
 <<"csrftoken=pdXwIcTFTAWFdNH57pIRQTUyBUfBl1Uz; sessionid=9510pia3jptvmycpnxcj337ox8zkp9xt">>}]},
  • Prefix は session で : で結合する
  • GET だと Value だけが返ってくるので base64 で decode する
  • pickle というシリアライズされた Python オブジェクトから Erlang Term に変換してくれるライブラリを使う
  • Redis への接続は Wooga の eredis を使った

redis 側からセッションを引っ張る:

Erlang R16B01 (erts-5.10.2) [source] [64-bit] [smp:2:2] [async-threads:10] [kernel-poll:true] [dtrace]

Eshell V5.10.2  (abort with ^G)
1> {ok, C} = eredis:start_link("127.0.0.1", 6379, 0).
{ok,<0.34.0>}
2> {ok, Value} = eredis:q(C, ["GET", "session:9510pia3jptvmycpnxcj337ox8zkp9xt"]).
{ok,<<"ZTNlMjAwYTY1ZDRiYmU4YjQzYTg3ZGM5ZGVkNmU4OGQ5YmZjMjY2ZDqAAn1xAShVEl9hdXRoX3VzZXJfYmFja2VuZHECVSlkamFuZ28uY29u"...>>}
3> V = base64:decode(Value).
<<"e3e200a65d4bbe8b43a87dc9ded6e88d9bfc266d:"...>>
4> [A, B] = binary:split(V, <<$:>>).
[<<"e3e200a65d4bbe8b43a87dc9ded6e88d9bfc266d">>,
 <<128,2,125,113,1,40,85,18,95,97,117,116,104,95,117,115,
   101,114,95,98,97,99,107,101,110,100,113,...>>]
5> pickle:pickle_to_term(B).
{dict,2,16,16,8,80,48,
      {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},
      {{[],[],[],[],[],[],
        [[<<"_auth_user_backend">>|
          <<"django.contrib.auth.backends.ModelBa"...>>]],
        [],
        [[<<"_auth_user_id">>|1]],
        [],[],[],[],[],[],[]}}}
6> D = pickle:pickle_to_term(B).
{dict,2,16,16,8,80,48,
      {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},
      {{[],[],[],[],[],[],
        [[<<"_auth_user_backend">>|
          <<"django.contrib.auth.backends.ModelBa"...>>]],
        [],
        [[<<"_auth_user_id">>|1]],
        [],[],[],[],[],[],[]}}}
7> dict:fetch_keys(D).
[<<"_auth_user_backend">>,<<"_auth_user_id">>]
8> dict:fetch(<<"_auth_user_backend">>, D).
<<"django.contrib.auth.backends.ModelBackend">>
9> dict:fetch(<<"_auth_user_id">>, D).
1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment