CORSトラブルが思わぬ方法で解決した話

# もう大丈夫だと思ってた

API方式のアプリケーション開発で度々話題になるCORSだが
ある日また実装者からヘルプが。

**「新環境の方でPUT/DELETEだとCORSエラーが起きちゃってるんですよ〜」**

OKOK、もう過去に散々ハマってるのでドンと来なさい。

```apache:追加した設定
<Directory /home/yakisoba/public_html>
# 〜中略〜
  SetEnvIf Origin "^http(s)?://(www\.)?(xxxx\.local|test\.chashu\.jp|localhost)(:\d+)?$" AccessControlAllowOrigin=$0
  Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
  Header set Access-Control-Allow-Methods "POST, GET, OPTIONS, PUT, DELETE"
  Header set Access-Control-Allow-Headers "Content-Type,x-xsrf-token"
  Header set Access-Control-Allow-Credentials true
</Directory>
```

で、

```sh
[root@ip-xxx-xxx-xxx-xxx conf.d]# httpd -t
Syntax OK
[root@ip-xxx-xxx-xxx-xxx conf.d]# service httpd graceful
```

**「設定しました！！」**

**「うーん...プリフライトリクエストでCORSエラーです...」**

**「」**

# 何が起きていたか

分
　か
　　ら
　　　な
　　　い。
## 調べたこと

・IP制限？
・Basic認証？
・EC2のセキュリティグループ？
・書き方が違う？
・文法ミス？
・サーバサイド（Laravel）の実装ミス？
・ファイルのパーミッションが変？
・ファイルのオーナー変？
・apache restartしてみる？
・LetsEncrypt切れてない？
・実はCORSが原因じゃなくない？

**全部違った**

# 不可思議な現象

同一サーバ内で検証用の環境はOPTIONSも通っており
localhostから通信も出来ている
同じ設定、同じソースなのに新しい環境の方だけCORSエラーになっている


```apache:検証環境の設定（大丈夫な方）
<Directory /home/ramen/tonkotsu/public_html>
# 〜中略〜
  SetEnvIf Origin "^http(s)?://(www\.)?(xxxx\.local|test\.chashu\.jp|localhost)(:\d+)?$" AccessControlAllowOrigin=$0
  Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
  Header set Access-Control-Allow-Methods "POST, GET, OPTIONS, PUT, DELETE"
  Header set Access-Control-Allow-Headers "Content-Type,x-xsrf-token"
  Header set Access-Control-Allow-Credentials true
</Directory>
```

```apache:新環境の設定
<Directory /home/yakisoba/public_html>
# 〜中略〜
  SetEnvIf Origin "^http(s)?://(www\.)?(xxxx\.local|test\.chashu\.jp|localhost)(:\d+)?$" AccessControlAllowOrigin=$0
  Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
  Header set Access-Control-Allow-Methods "POST, GET, OPTIONS, PUT, DELETE"
  Header set Access-Control-Allow-Headers "Content-Type,x-xsrf-token"
  Header set Access-Control-Allow-Credentials true
</Directory>
```

え、全く一緒？全く一緒！
ディレクティブの中まるっきり一緒！

## 2時間経過

なにか...ヒントはないのか...

```shell
-rw-r--r-- 1 root root 1355 Dec 12 20:41 php81-php.conf
-rw-r--r-- 1 root root  447 Jan 16 16:53 redirect.conf
-rw-r--r-- 1 root root   45 Dec 16 16:51 secure.conf
-rw-r--r-- 1 root root 1562 Feb  1 18:14 ssl.conf
-rw-r--r-- 1 root root 1266 Jun 30  2022 userdir.conf
-rw-r--r-- 1 root root  318 Oct 14 21:56 vhost.conf
-rw-r--r-- 1 root root  516 Jun 30  2022 welcome.conf
-rw-r--r-- 1 root root  516 Dec 17  2022 deflate.conf
```

なんだっけこれ
```
cat ./userdir.conf
```

```apache
︙
<Directory "/home/*/public_html">
    AllowOverride FileInfo AuthConfig Limit Indexes
    Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
    Require method GET POST OPTIONS
</Directory>
```
**!!!**
**違いがあった**

```apache
# ダメな方
<Directory /home/yakisoba/public_html>
# OKな方
<Directory /home/ramen/tonkotsu/public_html>
```

ホームディレクトリの階層が違っている

```apache
<Directory "/home/*/public_html">
    ︙
    Require method GET POST OPTIONS
</Directory>
```

で、userdir.confで```/home/xxxx/public_html```の場合は
```GET,POST,OPTIONS```のみ許可されている。

```apache
<Directory "/home/*/public_html">
    ︙
    # Require method GET POST OPTIONS
    # または　　
    Require method GET POST PUT DELETE OPTIONS
</Directory>
```

**動いた。**

# ホームディレクトリ内にドキュメントルートを設定する際の罠

デフォルトでメソッドが制限されている。
しかも```/home/xxx/public_html```の時限定。
原因は超シンプルだったけど気をつけましょう。

**おわり。**