CloudFrontの署名付Cookieの設定でつまずいた、という話。
CloudFrontで署名付Cookieを扱う
会員限定、期間限定とか、特定のユーザーにだけコンテンツを公開したいと思ったら、AWSのCloudFrontなら簡単にできるらしい。
CloudFrontを使用してプライベートコンテンツを供給する
http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html
署名付URLもしくは署名付Cookieを発行して、ユーザーを限定してS3へのアセットへのアクセスを許可することができるとのこと。使い分けとしてはざっくり以下の通り。
- 署名付URL: 単独の制限されたファイル(ダウンロードリンク等)に適している
- 署名付Cookie: 複数の制限されたファイル(動画のストリーミング等)に適している
Cookieのほうが自分の用途にあってるので、こちらを選択。
署名付き Cookie の使用
http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-cookies.html
CloudFrontのクロスドメインCookie問題
SDKを使って署名付Cookieを発行するわけですが、そうなるとこんな状況になります。
アプリ側のドメイン(署名付Cookieの発行) ==Cross Domain==> CloudFrontのドメイン(Cookieを判別してアクセス許可)
仕様上、別のドメインからはCookieは読めないわけなので、アプリとCloudFrontのサブドメイン以降は同じでなければいけない、ということになります。
本来、固有のドメインを取得して設定すればいいわけですが、まだ開発中のデモにお金かけたくない。。。
それなら、AWSがランダムに発行する xxxxxxxxx.cloudfront.net に合わせて、hostsファイルを設定してしまえばいいのでは? というわけで、local.cloudfront.net を設定してみました。
local.cloudfront.net ==Cross Domain==> xxxxxxxxx.cloudfront.net
start_time = (Time.now - 60).to_i
expire_time = 3.hours.from_now.to_i
policy = {
Statement: [
Resource: "https://local.cloudfront.net/sample/*",
Condition: {
DateLessThan: { "AWS:EpochTime" => expire_time },
DateGreaterThan: { "AWS:EpochTime" => start_time }
}
]
}
signer = Aws::CloudFront::CookieSigner.new(
key_pair_id: ENV['AWS_CLOUDFRONT_KEY_PAIR_ID'],
private_key_path: ENV['AWS_CLOUDFRONT_PRIVATE_KEY_PATH']
)
signer.signed_cookie('https://local.cloudfront.net/sample/*',
policy: policy.to_json
).each do |key, value|
cookies[key] = {
value: value,
domain: 'cloudfront.net',
path: '/',
secure: false
}
end
これで cloudfront.net に署名付Cookieが設定されて、ローカルから xxxxxxxxx.cloudfront.net のコンテンツにアクセスできる。。。 と思いきやCookieが設定されないではないですか!
Public Suffix List (PSL) とは?
色々調べてようやくつきとめたのが Public Suffix の存在。別名 Effective Top Level Domain (eTLD)。
A "public suffix" is one under which Internet users can (or historically could) directly register names. Some examples of public suffixes are .com, .co.uk and pvt.k12.ma.us. The Public Suffix List is a list of all known public suffixes.
Public Suffixはその下にインターネットユーザーが直接名前を設定できるドメインです。例えば、.com、.co.uk、pvt.k12.ma.usがその例です。
Avoid privacy-damaging "supercookies" being set for high-level domain name suffixes
プライバシーを侵害するSupercookieの設定を避けるためにも使われます。
https://publicsuffix.org/
要するに、.com や .co.uk なんて不特定多数に使われるドメインでCookieの読み書きできたらプライバシー上問題なので、Public Suffix Listに乗っているドメインにはCookieは設定できないよ、ということです。
それを踏まえて、Listを見てみると。。。
cloudfront.net
ありました。cloudfront.net は .com や .co.uk と同じレベルにあるということです。
原因が分かったので、今度は hosts を local.xxxxxxxxx.cloudfront.net として、 Cookieの設定ドメインを xxxxxxxxx.cloudfront.net にして、無事成功。
考えてみれば当然のことなのですが、cloudfront.net という名前からは意外と気づきませんでした(未熟)。Publix Suffixは膨大なリストなのでクラウド系のサービス使うときはチェックしてみてください。