メモ: nginxのAccess-Control-Allow-Origin設定

axios.js の入門で自分のwwwサーバーから値を取りたいと思ったところ
wwwサーバー側で `Access-Control-Allow-Origin`ヘッダーを出す必要があるとのこと。

## 動かしたかったJavascript

```html:a.html
<div id="result"></div>

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

<script>
function $id(id) {
        return document.getElementById(id);
}
function gethostbyaddr(ip) {
  axios.get('http://nginxserver.co.jp/api/ip.php?ip='+ip)
    .then(function (response) {
      $id("result").innerHTML = response.data;
    })
    .catch(function (error) {
      console.log(error);
    });
}
</script>

ip: <input type="text" id="ip" onChange="gethostbyaddr(this.value);" />
<input type="button" value="send" onClick="gethostbyaddr($id('ip').value);" />
```

```php:api/ip.php
<?php
if(!isset($_GET["ip"])) {
    $ip = $_SERVER['REMOTE_ADDR'];
} else {
    $ip = $_GET["ip"];
}
$hostname = gethostbyaddr($ip);
echo $hostname;
```

## nginx側での設定

nginx に以下追加し応答するようになった。

```diff:nginx.conf
 # デフォルトサーバの設定
 server {
     # バーチャルサーバが使用するアドレス、ポートを指定
     listen 80 default_server;
 
     # サーバの公開ディレクトリを指定
     # $document_root の値になる
     root /var/www/localhost/htdocs/;
     # インデックスページを指定
     index index.php index.html index.htm;
 
     # バーチャルサーバで使用するホスト名を指定
     server_name localhost;
 
     # URIごとにどのファイルを配信するか設定
     location / {
         # 指定したパスにファイルが存在するかどうか
         if (-f $request_filename) {
             # キャッシュの有効期限を設定
             expires 30d;
             break;
         }
         # CORS start
+        add_header Access-Control-Allow-Origin null;
+        add_header Access-Control-Allow-Methods "POST, GET, OPTIONS";
+        add_header Access-Control-Allow-Headers "Origin, Authorization, Accept";
+        add_header Access-Control-Allow-Credentials true;
         # CORS end
     }
 
     location ~ [^/]\.php(/|$) {
         # PATH_INFO 部の分割に使用する正規表現を指定
         # 一つ目 ( .+\.php ) は $fastcgi_script_name の値になり、二つ目 ( /.+ ) は $fastcgi_path_info の値になる
         fastcgi_split_path_info ^(.+\.php)(/.+)$;
         if (!-f $document_root$fastcgi_script_name) {
             return 404;
         }
         # FastCGI サーバへリクエストをプロキシする
         #fastcgi_pass 127.0.0.1:9000;
         fastcgi_pass unix:/var/run/php7-fpm.sock;
         # スラッシュで終わる URI の後に追加されるファイル名を設定
         # $fastcgi_script_name の値になる
         fastcgi_index index.php;
         # 設定ファイルを読み込む
         include fastcgi_params;
         # FastCGI サーバに渡されるべきパラメータを設定
         fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
         fastcgi_param PATH_INFO $fastcgi_path_info;
         fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;

         # CORS start
+        add_header Access-Control-Allow-Origin null;
+        add_header Access-Control-Allow-Methods "POST, GET, OPTIONS";
+        add_header Access-Control-Allow-Headers "Origin, Authorization, Accept";
+        add_header Access-Control-Allow-Credentials true;
         # CORS end
     }
 }
```

## Access-Control-Allow-Origin の値について

* `null` : `file:///` からのアクセスの時はnullを指定。
* `*` : 全許可。これするのは怖い
* `https://github.io/` : http://github.io からのアクセスのみ許可

* 複数箇所から許可する場合は以下のように書く。(nullとの判定はよくわからなかった。)
    * [nginx に CORS用 の設定をする（複数ドメイン編） - Qiita](http://qiita.com/cb-takahashi/items/934d1bf04f35808611de)

## curlでチェックができるっぽい

```bash:
curl -I -X OPTIONS -H "Origin: http://from.com" \
 http://nginxserver.co.jp
```

phpだと `$_SERVER['HTTP_ORIGIN']` というのもある様子


## phpで複数のクロスドメインを許可するCORS設定

* [複数のクロスドメインを許可するCORS設定 | ワイズリマインダー](https://reminder.ysrock.com/2018/03/22/複数のクロスドメインを許可するcors設定/)

```php
$reqHeaders = apache_request_headers();
$allowedOrigin = array(
		'http://hoge.com'
		,'http://www.hoge.com'
		,'https://hoge.com'
		,'https://www.hoge.com'
		);
if(in_array($reqHeaders['Origin'], $allowedOrigin)) {
	header("Access-Control-Allow-Origin: {$reqHeaders['Origin']}");
}
```