【AWS】AmplifyでDEV stageでもHTTPSを利用する

# はじめに
「AWS Amplify」を利用して開発する場合、概ね以下の順序でデプロイ＆動作確認をしていくかと思います。アプリの内容によってはDEV stageでの動作確認に困ることがあるので、その内容をまとめます。

1. ローカル環境で実装・動作確認
2. **DEV stageへデプロイ・動作確認**
3. PROD stageへデプロイ・動作確認

# TL;DR
- たとえ開発環境であっても、HTTPSが必要なケースがある
- DEV stageはS3のWeb Hostingを利用してコンテンツを公開する
- S3のWeb HostingはHTTPSを提供しない
- S3 API用のEndpointを利用すればHTTPSで参照できる

# やりたかったこと・内容
AWS Amplifyで作ったアプリをS3にデプロイし、これをHTTPSで公開したい、それも手動での設定変更を極力伴わない方法で、ということが発端となります。

Amplifyはそこそこ簡単にAWSを利用するアプリを作って公開することができます。アプリを格納しているディレクトリ上で「amplify publish」を実行するだけで、bundleされたJSファイル等が作られ、S3にアップロードされていきます。
まるでFirebaseのように簡単ですね。
![2018-11-12_03h34_06.png](https://qiita-image-store.s3.amazonaws.com/0/137777/cc037e49-4c4b-9d69-47c2-ec14ab44d260.png)

下記がAmplifyのチュートリアルとなります。

Getting Started
https://aws-amplify.github.io/docs/js/start

デプロイ先として、DEV stage及びPROD stageが用意されていますが、DEV stageはS3のWeb Hosting機能を利用してファイルを公開するものとなっています。
PROD stageは更にフロントにCloudFrontのdistributionを構築してコンテンツを公開できるようです。

Hosting
https://aws-amplify.github.io/docs/cli/hosting#stages

> # Stages
> For the amplify-category-hosting implementation, this is the default
> 
> - DEV: only S3 static web hosting
> - PROD: S3 and CloudFront

ここで問題となるのが、**Amplifyで用意されているDEV stageは原則としてHTTPのみでしか利用できない**、ということです。
上記のスクリーンショットからも分かりますが、PublishされたコンテンツのURLは「http://」から始まるものとなっています。
ドキュメントの末尾にもこんな記載があります。

> Note that the DEV stage using S3 static sites does not have full HTTPS end to end so it is only recommended for prototyping your app.


Webブラウザ上で実行するAPIのうち、幾つかは「http://」から始まるサイト上では動作が許可されないものがあります。（Secure Contextに後述）

したがってHTTPSを利用できない場合、Webアプリの動作確認を行うことができない場合があります。
私の場合、GeoLocation APIを利用するアプリを作っていたのですが、このAPIは「http://」から始まるURL上では許容されておりませんでした（※制限はWebブラウザの実装・バージョンに依存）
そのままではS3 Web Hosting動作確認を行うことができない状況でした。

# 対処方法
S3上に格納されたコンテンツをHTTPSで参照する方法があります。
詳細は後述するとして、下記のようにURLを変更することで、HTTPSでアクセスできるようになります。

ホスティング用のS3 Bucket名は「amplifyjsapp-20181111??????--hostingbucket」とします。リージョンはTokyo（ap-northeast-1）とします。
これはPublishの際に自動生成されています。

- オリジナルのURL

> http://amplifyjsapp-20181111??????--hostingbucket.s3-website-ap-northeast-1.amazonaws.com/index.html

- 変換後のURL

> https://amplifyjsapp-20181111??????--hostingbucket.s3-ap-northeast-1.amazonaws.com/index.html


# 解説
## S3のWeb HostingとS3 API Endpoint
何故、上記のようにURLを書き換えると、HTTPSでアクセスできるようになるのでしょうか。

まず、S3のWeb Hosting機能で公開する場合、利用できるのはHTTPのみとなります。
AWS S3 APIのEndpointを利用するようにURLを書き換えることで、HTTPSでアクセスできるようになります。

具体的な仕組みは下記記事によくまとまっておりますので、参照ください。

[S3のSSL通信 - Qiita](https://qiita.com/Yuhkih/items/1754ac9caf3f12d75946)

## Secure Context

Webブラウザ上で実行できるAPIの一部は、Secure Context下でのみ実行を許可されるものがあります。具体的なAPIは下記のMDNのドキュメントにまとまっています。
[Features restricted to secure contexts - Web security | MDN](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts/features_restricted_to_secure_contexts#Current_features_available_only_in_secure_contexts)

どの範囲がSecure Contextとみなされるのか、W3Cによる定義は下記にあります。
[Secure Contexts](https://www.w3.org/TR/secure-contexts/)

# Furthermore
## PROD stageでのHTTPSについて
未検証ですが、CloudFrontを併用するようなのでHTTPSでの利用は容易かと思います。
デフォルトの*.cloudfront.netも利用できるでしょうし、ACMを使ってカスタムドメインを利用することもできるでしょう。

# Secure Context関連情報
## ChromeのSecure Contextについて
少なくともChromeについては、localhostはHTTPSと同レベルのSecure Contextと見なして動作するようです。
https://www.chromestatus.com/feature/6269417340010496

なお、Secure Context下での実行が必要なAPIを、どうしてもInsecureなContextで動かしたい場合、「 --unsafely-treat-insecure-origin-as-secure="http://example.com" 」というオプションを付与してChromeを起動することで、とりあえず実行できるようになります。
しかしそれも全てのAPIではなく、対象は限られているようです。
https://sites.google.com/a/chromium.org/dev/Home/chromium-security/deprecating-powerful-features-on-insecure-origins

## その他のブラウザのSecure Context
※調査中…