はじめに
Lambda@Edge で Cookie の値を判断して処理をしたい。
そこで、以下の AWS 公式に記載されているコードを参考にして Cookie を dict に変換するような関数を書き利用していた。
def parseCookies(headers):
parsedCookie = {}
if headers.get('cookie'):
for cookie in headers['cookie'][0]['value'].split(';'):
if cookie:
parts = cookie.split('=')
parsedCookie[parts[0].strip()] = parts[1].strip()
return parsedCookie
しかし、ある時を堺に更新したはずの Cookie の値が取得できず、ずっと古い Cookie の値が取得されるようになってしまった。 ただし、特定の環境のみであり、ごく一部の環境でのみこれが発生した。
原因
直接の原因は以下の2点が同時に発生していたためである。
- Cookie のパスを
Path=/
からPath=/private/
以下に変更した -
Path=/
の Cookie がブラウザ上に残り続けていた (Expired=Sessionだったが、ブラウザを閉じていなかった)
まず、同名かつ Path が異なる Cookie が2つあるため、RFC6225 に基づいて Path=/private/
のデータが Cookie の先に来るように(ほとんどすべての環境では)送られる。
実際にLambdaでは以下のような Cookie を確認した (Cookie名はtokenを利用)。
[{
'key': 'cookie',
'value': 'token=<pathが/private/のvalue>; token=<pathが/のvalue>'
}]
今回のケースでは Path=/
が更新されていない古いデータであり、引き渡されたデータの後に来ている。
しかし、AWS で提供されているコードは「Cookie名が同じ場合は後からきたデータで上書きする」実装になっている。 そのため、今回の記事のような問題が発生していた。
まとめ
Cookie 名を変えた場合は古いデータがキャッシュとして残っているケースがあり、それが予期せぬ挙動を引き起こすことが分かった。
今回は開発レベルなので特に問題はなかったが、実運用では Cookie の Name を同じままで Path のみを書き換える場合、古い Cookie をどうするかはちゃんと考えた方が良いだろう。
参考