CloudFrontを導入してもUser-agentの値は書き換えられないようにする方法。

# はじめに
CloudFrontの導入の際に、特に何も設定を行わないと、CloudFrontを通過する時点で_User-agent_の値が「Amazon CloudFront」に書き換えられてしまいます。
その場合、今まで_User-agent_の情報をもとにPCサイトやモバイルサイトへの振り分けを行っていた場合、うまく振り分けられなくなってしまいます。
今回はそういう状況を回避するため_User-agent_の値を導入前と同じように取得するための設定を行います。
また、CloudFrontはELBまたはS3に対してしか導入できない(2016年4月現在)ため、今回はELBを利用した以下の構成で行います。
![User-agent.png](https://qiita-image-store.s3.amazonaws.com/0/82090/78b00c76-f008-4963-5b42-ec7123d6d633.png)


# 0. 事前準備
今回は以下のphpファイルをサーバに配置して_User-agent_の値を確認します。

```php:ua.php
<?php
$ua = $_SERVER["HTTP_USER_AGENT"];
echo "$ua";
?>
```

まずは直接サーバまたはELBへアクセスした際に取得できる_User-agent_の値を確認します。
今回はSafariでサイトへアクセスするため_User-agent_は以下のように表示されます。
![cloudfront_1_user-agent_01.png](https://qiita-image-store.s3.amazonaws.com/0/82090/d0c29473-0846-30f7-6008-87507cb168e3.png)

```text:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/601.5.17 (KHTML, like Gecko) Version/9.1 Safari/601.5.17
```

また、CloudFront経由での_User-agent_も確認します。
デフォルト設定の場合、CloudFrontを通すと_User-agent_は以下のように見えます。
![cloudfront_1_user-agent_02.png](https://qiita-image-store.s3.amazonaws.com/0/82090/6fb41712-230e-69ee-fc84-caddd7968bd1.png)

```text:
Amazon CloudFront
```

もし、今まで_User-agent_の情報を利用して処理を行っていたとすると、このままでは影響が出てしまいます。
対処についてやり方は色々あると思いますが、今回は_User-agent_を今まで通りの値で通信できるように設定します。


# 1. Distributionの作成
- [Create Distribution]をクリックします。
![cloudfront_2_distribution_01.png](https://qiita-image-store.s3.amazonaws.com/0/82090/5f4c635e-87ea-a7e8-890f-129e818ffaac.png)

#### Step1. Select a delivery method for your content.
- Webの方の[Get Started]をクリックします。
![cloudfront_2_distribution_02.png](https://qiita-image-store.s3.amazonaws.com/0/82090/99fe535c-5e3f-e14d-cfd9-36c67d9ad892.png)

#### Step2. Create Distribution
- Origin SettingsのOrigin Domain Nameで導入先のELBを指定して「Create Distribution」をクリックします。
![cloudfront_2_distribution_03.png](https://qiita-image-store.s3.amazonaws.com/0/82090/1d312c9f-fc00-3c0c-8cab-265d37f39965.png)
![cloudfront_2_distribution_04.png](https://qiita-image-store.s3.amazonaws.com/0/82090/95c35574-c3e8-f5c8-cb75-ec892e932283.png)


# 2. Behaviorsの設定
- 作成した「Distribution」にチェックを入れ「Distribution Settings」をクリックします。
![cloudfront_3_behavior_01.png](https://qiita-image-store.s3.amazonaws.com/0/82090/8ac8b9d4-67d0-3e41-c93a-d6a7ef470810.png)

- 「Behaviors」タブをクリックし編集する対象(今回はDefault)にチェックを入れ「Edit」をクリックします。
※新規で作成したい場合は「Create Behavior」をクリックしてください。
![cloudfront_3_behavior_02.png](https://qiita-image-store.s3.amazonaws.com/0/82090/2acf3cbd-3dea-7b39-022d-5533a9cd82fc.png)


## Edit Behavior
#### Default Cache Behavior Settings
- Forward HeadersをWhitelistに変更します。
![cloudfront_3_behavior_03.png](https://qiita-image-store.s3.amazonaws.com/0/82090/df32eb4f-76fc-7cdd-06fb-1f2552237ec7.png)

- Whitelist Heaadersの項目が現れるので_User-agent_と入力した後に「Add Custom >>」をクリックして追加します。
![cloudfront_3_behavior_04.png](https://qiita-image-store.s3.amazonaws.com/0/82090/40c2afec-7056-1957-0af0-fb66acb703f2.png)

- 追加されたことを確認したら、右下の「Yes, Edit」をクリックして完了です。
![cloudfront_3_behavior_05.png](https://qiita-image-store.s3.amazonaws.com/0/82090/d96d59f1-3431-0003-1c87-eb18a9b05cf9.png)
![cloudfront_3_behavior_06.png](https://qiita-image-store.s3.amazonaws.com/0/82090/34d3b9f9-d88d-171d-ed4d-b526e065a84c.png)

しばらく時間が経つとUser-agentが今まで通りの値になるのが確認できます。
![cloudfront_1_user-agent_03.png](https://qiita-image-store.s3.amazonaws.com/0/82090/e2f27c9f-b52e-07aa-4f42-8de3c447c505.png)

あらかじめTTLを短くしておくと切り替わるのが早いので確認しやすいです。


# おわりに

今回の設定は_User-agent_で振り分けたい場合に有効的ですが、キャッシュ効率が悪くなってしまうため推奨されていません。

```text:内容
"Some headers have a lot of possible values, and caching based on the values in these headers would cause CloudFront to forward more requests to your origin. We recommend that you do not cache based on the following headers: User-Agent"
```
```text:意味
いくつかのヘッダーは多くの値を持ち、それらのヘッダーの値をもとにキャッシュしているため、CloudFrontが多くのリクエストをオリジンへ転送する要因となります。私たちは次のヘッダーをキャッシュしないことを薦めます。User-Agent
```

また、CloudFrontはUser-agentヘッダーの値に基づいてデバイスタイプを判定するための設定がWhitelist Headersで設定できます。

```text:WhitelistHeaders
CloudFront-Is-Desktop-Viewer
CloudFront-Is-Mobile-Viewer
CloudFront-Is-SmartTV-Viewer
CloudFront-Is-Tablet-Viewer
```

なので、端末の種類によって振り分けを行いたい場合はこの設定を利用するのが好ましいです。