Swaggerでテスト〜CORS対策〜

## はじめに

swagger v2.0の場合だと「npm install cors --save」で「app.js」を編集していた。
でもローカルのLaravelのサーバは「 http://localhost:80/api 」だから違う気がした。
というのも、「swagger.yaml」ファイルのversionが2系の場合、CORS対応のために「npm install cors --save」をインストールして「app.js」を編集すれば、「 http://localhost:10010/swagger 」を開くとJSON形式のSwagger定義ファイルが取得できる。

詳しくはこちらの記事💁[SwaggerでRESTful環境を構築する](https://qiita.com/poruruba/items/72d8c85f8923bc78b918)

この記事では、「openapi.yaml」ファイルが最新の3系の場合、CORS対策の方法が「npm install cors --save」ではバージョンが違うので解決できなかったので共有する。
Swaggerが2系の環境構築から3系の環境構築までの成功の道のりは下記の記事を参考。
[Swaggerでテスト環境構築〜swagger.yaml編〜](https://qiita.com/tetsuyamakabe/items/39a1e992919fd4695b36)
[Swaggerでテスト環境構築〜openapi.yaml編〜](https://qiita.com/tetsuyamakabe/items/ddda8a232f38b49f1cba)

## CORSとは？

> オリジン間リソース共有 (Cross-Origin Resource Sharing, [CORS](https://developer.mozilla.org/ja/docs/Glossary/CORS)) は、追加の [HTTP](https://developer.mozilla.org/ja/docs/Glossary/HTTP) ヘッダーを使用して、ある[オリジン](https://developer.mozilla.org/ja/docs/Glossary/Origin)で動作しているウェブアプリケーションに、異なるオリジンにある選択されたリソースへのアクセス権を与えるようブラウザーに指示するための仕組みです。ウェブアプリケーションは、自分とは異なるオリジン (ドメイン、プロトコル、ポート番号) にあるリソースをリクエストするとき、オリジン間 HTTP リクエストを実行します。
> 

（引用：[オリジン間リソース共有 (CORS)](https://developer.mozilla.org/ja/docs/Web/HTTP/CORS)）

調べると「**barryvdh/laravel-cors**」というライブラリをインストールする方法もあるみたい。

（参考記事：[Laravelでクロスオリジン（CORS）に対応する方法](https://torii-world.net/laravel-cors/)）

簡単に言えば、あるWebページから別のドメインのリソースにアクセスする際のセキュリティ対策のこと。

![19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/4c125e9b-d355-cff4-ca52-d3589124e64a.png)



swagger-uiでテストすると、CORSオリジンエラーになってしまう。

![20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/b90729a5-fb16-57a4-1981-b7366dd82a7f.png)


例：「docker-compose.yaml」

```docker
    swagger-ui:
      image: swaggerapi/swagger-ui
      container_name: "post-swagger-ui"
      ports:
        - "1112:8080"
      volumes:
        - ./openapi:/openapi
      environment:
        SWAGGER_JSON: /openapi/openapi.yaml
```

「 http://localhost/api/session 」に対するリクエストが「 http://localhost:1112/ 」（swagger-uiのポート番号）から発信されている。

サーバーがCORSヘッダーを提供していないため、ブラウザがリクエストをブロックしているという認識でいいかな？

## 環境構築〜config/cors.phpでCORS対策〜

openapiのバージョンが3系の場合、どのようにcors対策をすればいいのか？

１、「config/cors.php」の中はデフォルトで下記のようになっている。

```php
<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Cross-Origin Resource Sharing (CORS) Configuration
    |--------------------------------------------------------------------------
    |
    | Here you may configure your settings for cross-origin resource sharing
    | or "CORS". This determines what cross-origin operations may execute
    | in web browsers. You are free to adjust these settings as needed.
    |
    | To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
    |
    */

    'paths' => ['*'],

    'allowed_methods' => ['*'],

    'allowed_origins' => ['*'],

    'allowed_origins_patterns' => [],

    'allowed_headers' => ['*'],

    'exposed_headers' => false,

    'max_age' => false,

    'supports_credentials' => false,

];
```

２、「'allowed_origins’」に「swagger-ui」のポート番号のリクエストオリジンを許可するように設定。

```php
<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Cross-Origin Resource Sharing (CORS) Configuration
    |--------------------------------------------------------------------------
    |
    | Here you may configure your settings for cross-origin resource sharing
    | or "CORS". This determines what cross-origin operations may execute
    | in web browsers. You are free to adjust these settings as needed.
    |
    | To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
    |
    */

    'paths' => ['*'],

    'allowed_methods' => ['*'],

    'allowed_origins' => ['http://localhost:1112'], // ここにswagger-uiのポート番号を追加

    'allowed_origins_patterns' => [],

    'allowed_headers' => ['*'],

    'exposed_headers' => false,

    'max_age' => false,

    'supports_credentials' => false,

];
```

## まとめ

CORSは異なるオリジンからのリクエストに対する制御であり、クライアントとサーバーのやり取りにおいて、セキュリティ上の問題を回避するための仕組みということ。

### **同一オリジンポリシー**
Webブラウザは、セキュリティ上の理由から、異なるオリジンからのJavaScriptからのHTTPリクエストを制限している。
同一オリジンポリシーにより、Webページが異なるオリジンの情報にアクセスするのを制限し、クロスサイトスクリプティングなどの攻撃から保護する。
開発ツールのコンソールにエラーを発見👀
![スクリーンショット 2024-03-04 21.53.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/b0f431c0-7505-aa4e-4755-362a3bdcc509.png)
（参考記事：[同一オリジンポリシー - ウェブセキュリティ | MDN developer.mozilla.org](https://developer.mozilla.org/ja/docs/Web/Security/Same-origin_policy)）

### **CORSヘッダー**
クライアントが異なるオリジンからのリソースにアクセスするためには、サーバーがCORSヘッダーを含む必要がある。これにより、Webブラウザはリソースへのアクセスが許可されているかどうかを確認し、許可されていればリクエストを続行する。
開発ツールのNetWorkタブを確認👀
![スクリーンショット 2024-03-04 22.03.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/3c47d25a-d655-2097-adc9-24ab1ba51634.png)
（参考記事：[オリジン間リソース共有 (CORS) - HTTP | MDN developer.mozilla.org](https://developer.mozilla.org/ja/docs/Web/HTTP/CORS)）

### **CORSの設定**
サーバー側でCORSを設定するには、以下のようなヘッダーをレスポンスに含める必要がある。

```php
Access-Control-Allow-Origin: * 
```

すべてのオリジンからのアクセスを許可するもの。
実際の運用では、必要なオリジンのみを許可するように指定する。
（参考記事：[オリジン間リソース共有 (CORS) - HTTP | MDN developer.mozilla.org](https://developer.mozilla.org/ja/docs/Web/HTTP/CORS)）

参考記事：
[Origin (オリジン) - MDN Web Docs 用語集: ウェブ関連用語の定義 | MDN developer.mozilla.org](https://developer.mozilla.org/ja/docs/Web/HTTP/CORS)
[同一オリジンポリシー - ウェブセキュリティ | MDN developer.mozilla.org](https://developer.mozilla.org/ja/docs/Web/Security/Same-origin_policy)
[オリジン間リソース共有 (CORS) - HTTP | MDN developer.mozilla.org](https://developer.mozilla.org/ja/docs/Web/HTTP/CORS)
[LaravelでのCORS対策とmiddlewareへの理解](https://qiita.com/niconiconainu/items/a507aa0b46037df1b139)
[Laravelでクロスオリジン（CORS）に対応する方法](https://torii-world.net/laravel-cors/)
[同一オリジンポリシーを理解する](https://qiita.com/ymbn/items/cc69dc3eccf5a13bbeed)
[同一オリジンポリシーとCORS](https://qiita.com/hinako_n/items/133be327d2809a6c9169)
[【図解】同一オリジンポリシー・CORSとは](https://shukapin.com/infographicIT/origin-policy)
[同一オリジンポリシーを理解する。CORSエラーの原因と回避方法！](https://ugo.tokyo/same-origin-policy/)