4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

cloudfront.netがPublic Suffixで困ったという話

Last updated at Posted at 2017-04-17

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は膨大なリストなのでクラウド系のサービス使うときはチェックしてみてください。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?