以下のソースコードを読んでいきました。
# -*- coding: utf-8 -*-
最初はこのコードから始まります。Pythonの教科書などで冒頭に書けと言われているやつですね。
"""
flask.sessions
~~~~~~~~~~~~~~
Implements cookie based sessions based on itsdangerous.
:copyright: 2010 Pallets
:license: BSD-3-Clause
"""
sessonの内容を記述するコードのようです。itsdangerousというパッケージがあるようで、以下のリンクに説明が書いてあるようです。itsdangerousを使って、cookieベースのセッションを実装しているようです。
ここではitsdangerousのBadSignatureとURLSafeTimedSerializerがインポートされてます。
from itsdangerous import BadSignature
from itsdangerous import URLSafeTimedSerializer
itsdangerousについては、以下のようなコードが例として示されています。
from itsdangerous import Signer
s = Signer('secret-key')
s.sign('my string')
'my string.wh6tMHxLgJqB6oY1uT73iMlyrOA'
以下のコードでサインを確認できます。
s.unsign('my string.wh6tMHxLgJqB6oY1uT73iMlyrOA')
'my string'
さて、'my string.wh6tMHxLgJqB6oY1uT73iMlyrOA'の最後のAをOに変えてみたらどうでしょうか?
s.unsign('my string.wh6tMHxLgJqB6oY1uT73iMlyrOO')
以下のような出力になります。
BadSignatureTraceback (most recent call last)
<ipython-input-23-8d912c717760> in <module>()
----> 1 s.unsign('my string.wh6tMHxLgJqB6oY1uT73iMlyrOO')
/usr/local/lib/python2.7/dist-packages/itsdangerous/signer.pyc in unsign(self, signed_value)
167 if self.verify_signature(value, sig):
168 return value
--> 169 raise BadSignature("Signature %r does not match" % sig, payload=value)
170
171 def validate(self, signed_value):
BadSignature: Signature 'wh6tMHxLgJqB6oY1uT73iMlyrOO' does not match
ここで、インポートされていた別のモジュールのBadSignature例外が現れましたね。
では、以下のようにしてみます。
try:
s.unsign('my string.wh6tMHxLgJqB6oY1uT73iMlyrOO')
except BadSignature:
print("BadSignature Occurres!!")
"BadSignature Occurres!!"
見事にキャッチしてくれましたね。このようなBadSignature例外のキャッチのためにBadSignatureのインポートが必要なのです。
URLSafeSerializerについては、以下のようなエグザンプルコードがありました。シークレットキーによって、データに対して、署名をしてくれるようです。
>>> from itsdangerous import URLSafeSerializer
>>> s = URLSafeSerializer('secret-key')
>>> s.dumps([1, 2, 3, 4])
'WzEsMiwzLDRd.wSPHqC0gR7VUqivlSukJ0IeTDgo'
>>> s.loads('WzEsMiwzLDRd.wSPHqC0gR7VUqivlSukJ0IeTDgo')
[1, 2, 3, 4]
ところで、違ったシークレットキーでデコードしてみたらどうなるんでしょうか?
from itsdangerous import URLSafeSerializer
s = URLSafeSerializer('secret-key')
s2 = URLSafeSerializer('secret-key2')
s2.loads(s.dumps([1, 2, 3, 4]))
BadSignatureエラーが生成されます。
BadSignatureTraceback (most recent call last)
<ipython-input-27-0276404e6c12> in <module>()
2 s = URLSafeSerializer('secret-key')
3 s2 = URLSafeSerializer('secret-key2')
----> 4 s2.loads(s.dumps([1, 2, 3, 4]))
/usr/local/lib/python2.7/dist-packages/itsdangerous/serializer.pyc in loads(self, s, salt)
187 except BadSignature as err:
188 last_exception = err
--> 189 raise last_exception
190
191 def load(self, f, salt=None):
BadSignature: Signature 'wSPHqC0gR7VUqivlSukJ0IeTDgo' does not match
つまるところ、BadSignatureとは、署名が一致しなかった時に生成される例外のようです。つまるところ、itsdangerousとは、署名をマネージしてくれるフレームワークということになります。信頼できない場所で、メッセージのやりとりをするWebなどでは、必須の機能になりますね。
この記事を書くために、Google Collaboratoryを使いました。