WerkzeugのSecureCookieを試してみた。
最近Werkzeugで何か作って遊んでます。何となく低レイヤーっぽいイメージだったので今まで手を付けずにいたのですが、触ってみたら意外と高機能っぽい。
で、今回はそのうちの一つ、SecureCookieとやらを使ってみます。 暗号化されたクッキーを保存してくれるものらしい。 flaskのセッションみたいな感じで、サーバサイドには何も置かずにデータを保存したり出来る。便利そう。
試しに書いてみたコードはこんな感じ。
from werkzeug.wrappers import Request,Response
from werkzeug.contrib.securecookie import SecureCookie
@Request.application
def app(request):
if request.path == '/':
session = SecureCookie.load_cookie(request, secret_key=b'this is password')
return Response(session.get('last_path'))
else:
response = Response('hello')
session = SecureCookie(secret_key=b'this is password')
session['last_path'] = request.path
session.save_cookie(response)
return response
if __name__ == '__main__':
from werkzeug.serving import run_simple
run_simple('localhost', 5000, app)
トップページにアクセスすると、前回アクセスしたページを教えてくれます。っても、ブラウザによっては/favicon.ico
で固定だったりしてつまらないけれど。
ブラウザに設定されたクッキーを確認すると、"hhwsr1IWDIsZGi1VVaI6IiXrjMg=?last_path=gANYDAAAAC9mYXZpY29uLmljb3EALg=="
みたいなよく分からない値がセットされていると思います。
SecureCookieってクラスが本体。
>>> SecureCookie(secret_key=b'abc')
こんな感じで普通にインスタンス化。
secret_key
は無くてもインスタンス化できますが、どうせ後で設定しなきゃいけないのでインスタンス化するときに設定する事をおすすめします。
作ったインスタンスは
>>> s = SecureCookie(secret_key=b'abc')
>>> s['a'] = 1
>>> s['b'] = (1,2)
>>> s
<SecureCookie {'a': 1, 'b': (1, 2)}>
みたいな感じで辞書型風に扱うことが出来る。 キーに数値を指定することも出来ますが、シリアライズするときにエラー吐きます。注意。キーは必ず文字列にしましょう。
ちなみに、
>>> SecureCookie({'a': 1, 'b': (1,2)}, secret_key=b'abc')
<SecureCookie {'a': 1, 'b': (1,2)}>
のようにしてクッキーの中身を最初から指定することもできます。
作ったデータは
>>> s = SecureCookie({'a': 1, 'b': (1,2)}, secret_key=b'abc')
>>> s.serialize()
b'UnEDwvLu0hGIk5h1Zdvjr0RVlEo=?a=gANLAS4=&b=gANLAUsChnEALg=='
のようにすれば見れる。見たってしょうがない気もする。
Responseに保存するときは
>>> r = Response()
>>> s = SecureCookie({'a': 1, 'b': (1,2)}, secret_key=b'abc')
>>> s.save_cookie(r)
みたいな感じにする。
r.headers
を見ると、Set-Cookieヘッダが追加されているのが確認できるはずです。
後はクッキーを設定したResponseを返してやれば、クライアントに設定できる。
クライアントから送られてきたクッキーは
>>> SecureCookie.load_cookie(request)
<SecureCookie {'a': 1, 'b': (1,2)}>
てな感じで受け取る。
初期設定だと保存されるクッキーのキーはsessionになっていますが、load_key
/save_key
をするときに
>>> r = Response()
>>> s = SecureCookie({'a': 1, 'b': (1,2)}, secret_key=b'abc')
>>> s.save_cookie(r)
>>> r.headers
Headers([('Content-Type', 'text/plain; charset=utf-8'), ('Set-Cookie', 'session="UnEDwvLu0hGIk5h1Zdvjr0RVlEo=?a=gANLAS4=&b=gANLAUsChnEALg=="; Path=/')])
>>> r = Response()
>>> s = SecureCookie({'a': 1, 'b': (1,2)}, secret_key=b'abc')
>>> s.save_cookie(r, key='keystring')
>>> r.headers
Headers([('Content-Type', 'text/plain; charset=utf-8'), ('Set-Cookie', 'keystring="UnEDwvLu0hGIk5h1Zdvjr0RVlEo=?a=gANLAS4=&b=gANLAUsChnEALg=="; Path=/')])
何かこんな感じで設定できる。
うん、割と便利だ。 ていうか、ほとんどflaskのsessionその物な気がする? 結構楽しいぞwerkzeug。