個人的備忘録：CORS とは？ Web 開発者が知っておくべきクロスオリジン通信の仕組みをまとめた

### はじめに
Web 開発をしていると、フロントエンドとバックエンドが異なるオリジン（ドメイン）で動作することがよくあります。

:::note info
**しかし、そのままではブラウザのセキュリティ機能によってリクエストがブロックされることがあります。**
:::

この問題を解決する仕組みが CORS（Cross-Origin Resource Sharing）です。本記事では、CORS の概要とその仕組み、設定方法について詳しく解説します。

### CORS（Cross-Origin Resource Sharing）とは？
CORS（Cross-Origin Resource Sharing）は、異なるオリジン（ドメイン、プロトコル、ポート）の間でリソースをやり取りする際に発生するセキュリティ制限を緩和する仕組みです。

https://aws.amazon.com/jp/what-is/cross-origin-resource-sharing/

Webブラウザは、セキュリティ上の理由から、異なるオリジンのリソースへのアクセスを制限する「同一オリジンポリシー（Same-Origin Policy, SOP）」を持っています。

**参考にした記事**

https://qiita.com/att55/items/2154a8aad8bf1409db2b

この制限を適切に管理するために CORS が利用されます。

### 同一オリジンポリシーとは？
Webブラウザはスクリプト（JavaScript など）がアクセスできるリソースを同じオリジン内に限定するポリシーを持っています。

#### オリジン（Origin）の定義
オリジンは、**プロトコル + ドメイン + ポート** の組み合わせで定義されます。

#### 例
| URL | オリジン |
|------|---------|
| `https://example.com:443` | オリジンA |
| `http://example.com:80` | オリジンB（プロトコルが異なるので別オリジン） |
| `https://api.example.com:443` | オリジンC（サブドメインが異なるので別オリジン） |
| `https://example.com:8080` | オリジンD（ポートが異なるので別オリジン） |

異なるオリジンにリクエストを送ると、CORS 制限によってエラーになります。

### CORSの仕組み
サーバー側がレスポンスヘッダーで適切な CORS 設定を行うことで、異なるオリジン間の通信を許可できます。

#### 例：CORS を許可するレスポンスヘッダー
```
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: Content-Type
```

- `Access-Control-Allow-Origin`: 許可するオリジンを指定（`*` で全オリジン許可）
- `Access-Control-Allow-Methods`: 許可する HTTP メソッド（例：`GET, POST, PUT, DELETE`）
- `Access-Control-Allow-Headers`: 許可するリクエストヘッダー（例：`Content-Type`）

### CORSの種類
#### シンプルリクエスト（Simple Request）
以下の条件を満たすリクエストは「シンプルリクエスト」として扱われ、プリフライト（事前リクエスト）なしで送信されます。

- HTTP メソッドが `GET`, `POST`, `HEAD` のいずれか
- `Content-Type` が `application/x-www-form-urlencoded`, `multipart/form-data`, `text/plain` のいずれか
- `Authorization` ヘッダーを含まない

#### 例：シンプルリクエスト
```javascript
fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => console.log(data));
```
サーバーが `Access-Control-Allow-Origin` を適切に設定していれば、ブラウザはリクエストを許可します。

### Echo フレームワークでの CORS 設定
Go 言語の Echo フレームワークを使用して CORS を設定する場合、`middleware.CORSWithConfig` を利用できます。

#### 例：Echo での CORS 設定
```go
// Middleware 設定
e.Use(middleware.Logger())
e.Use(middleware.Recover())
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
    AllowOrigins:     []string{"http://localhost:5173"},
    AllowMethods:     []string{http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete, http.MethodPatch, http.MethodOptions},
    AllowHeaders:     []string{echo.HeaderOrigin, echo.HeaderContentType, echo.HeaderAccept, echo.HeaderAuthorization},
    AllowCredentials: true,
}))
```

#### 設定内容
- `AllowOrigins`: 許可するオリジン（例では `http://localhost:5173` のみ許可）
- `AllowMethods`: 許可する HTTP メソッド（`GET`, `POST`, `PUT`, `DELETE`, `PATCH`, `OPTIONS`）
- `AllowHeaders`: 許可するヘッダー（`Origin`, `Content-Type`, `Accept`, `Authorization`）
- `AllowCredentials`: クッキーなどの認証情報を許可する場合は `true` に設定

この設定を行うことで、フロントエンドとバックエンドが異なるオリジンに存在する場合でも、安全に通信を行うことができます。

### まとめ
CORS は、異なるオリジン間でのリクエストを安全に行うために必要な仕組みです。ブラウザの同一オリジンポリシーにより、通常は制限されるリクエストを、サーバー側の適切な設定によって許可することができます。

:::note note
**特に、バックエンド API を提供する場合には、適切な CORS 設定を行うことで、フロントエンドアプリケーションとのスムーズな通信を実現できます。**
:::

開発時にはローカル環境での動作確認や、セキュリティを考慮した設定を心がけることが重要です。