Laravelで従来CORSのヘッダーを設定するには barryvdh/laravel-cors のパッケージが提供するミドルウェアがスタンダードだったらしいのですが、このパッケージは2019年末よりfruitcake/laravel-corsが導入されています。
またLaravel 7.X よりこのパッケージは初期テンプレートにバンドルされ、初期状態で利用可能になりました。
\Fruitcake\Cors\HandleCors::class
config/cors.phpで設定可能です。
問題
そして、
フロントエンド側のメインドメイン
https://example.comから
バックエンド側のサブドメイン ( basic認証あり )
https://api.example.com/api/register
に対してAPI (POST送信) を叩いた時corsに引っかかりました。甘かった。
Access to XMLHttpRequest at 'https://api.example.com/api/register?name=%sample&text=&smaple' from origin 'https://example.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
:authority: api.example.com
:method: OPTIONS
access-control-request-headers: authorization
access-control-request-method: POST
origin: https://example.com
同一オリジン下でのbasic認証有りの場合は、
HTTPリクエストの際にAuthorizationヘッダーに情報を付与することで、認証に成功するはずです。
しかしCORSに該当するリクエストで、単純なリクエストではない場合、
具体的には以下のいずれかに当てはまる場合プリフライトリクエストを送る。
・HTTPメソッドがGET, POST, HEAD以外
・HTTPヘッダにAccept, Accept-Language, Content-Language, Content-Type以外のフィールドが含まれる
・Content-Typeの値はapplication/x-www-form-urlencoded, multipart/form-data, text/plain以外
①ブラウザがプリフライトリクエストに変換し、HTTP の OPTIONS リクエストメソッドを用いて、送信(サーバーから対応するメソッドの一覧を収集すること)。
②プリフライトを飛ばしてしまうと、プリフライトリクエストには認証情報は乗らないので、プリフライトリクエスト自体がBASIC認証で弾かれる。
という現象に陥りました。
解決方法
今回のAPIは短期的に利用するものであったので、basic認証自体を解除しました。
####他に解決方法としては、
プリフライトが飛ばないようにリクエストを組む。
そのためには、js側でAuthorizationヘッダではなく、XMLHttpRequestのオプションでBASIC認証のIDとパスワードを指定します。withCredentials,trueのプロパティを追加する。
httaccess側では、
Access-Control-Allow-Credentials,trueを返す設定を追記するとのことでした。