
問題の発生
Ginフレームワークを使用してAPIを構築する過程で、次のような
CORS
関連のエラーが発生しました:Access to XMLHttpRequest at '${Gin ip Link}' from origin '${Frontend Origin URL}' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
このエラーは、サーバーが特定のオリジンからのリクエストを拒否する際に生じます。通常、ブラウザはセキュリティ上の理由から、異なるオリジンへのスクリプトによるリソースへのアクセスを制限しています。これを「同一オリジンポリシー」といい、
CORS
はこのポリシーの柔軟な運用を可能にします。以前の
CORS
設定は以下のようになっていました:router := gin.Default() router.Use(cors.New(cors.Config{ AllowOrigins: []string{"http://localhost:3000", "http://127.0.0.1:3000"}, AllowMethods: []string{"GET", "POST", "PATCH", "PUT", "DELETE"}, AllowHeaders: []string{"Origin", "Content-Length", "Content-Type", "Authorization"}, ExposeHeaders: []string{"Content-Length"}, }))
しかし、この設定では望まれる動作をせず、エラーが発生しました。
問題解決のアプローチ
CORS
設定を以下のように変更しました:router.Use(CORS()) // 新たに定義したCORSミドルウェアの使用 ... func CORS() gin.HandlerFunc { return func(c *gin.Context) { c.Writer.Header().Set("Access-Control-Allow-Origin", "http://localhost:3000") // 認証情報を含むリクエストを許可 c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") // 必要なヘッダーを明確に設定 c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With") c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, PATCH, GET, PUT, DELETE, OPTIONS") // OPTIONSリクエストに対しては204 No Contentを返す if c.Request.Method == "OPTIONS" { c.AbortWithStatus(204) return } c.Next() } }
この変更により、
Access-Control-Allow-Origin
を特定のドメインに限定し、CORS
ポリシーに従って必要なヘッダーを明確に設定しました。これにより、もともと発生していたエラーを成功的に解決することができました。CORSとは?

CORS(Cross-Origin Resource Sharing)
は、異なるドメイン間でのリソース共有を可能にするためのウェブブラウザのセキュリティメカニズムです。これにより、ウェブページは異なるオリジン(ドメイン、スキーム、ポートが異なる場所)のリソースにアクセスできるようになります。同一オリジンポリシーによる制限を緩和しながらも、セキュリティを確保することが可能です。Origin
https://google.com:80/search?page=1
このURLは私たちが毎日目にするGoogleのURLです。
上記の構成要素のうち、
Protocol(https://)
+ Host(google.com)
+ Port(80)
3つが同じなら同じソース(Origin)と言います。CORSが必要な理由
私たちはウェブで
<img>
<script>
<frame>
<video>
タグを使用しながら、新しいリソースを外部から取り込むことができます。もし、銀行のホームページに入ったら、悪質なコードが植えられた
<script>
ファイルが含まれているevil.comページを開いたらどうなるでしょうか?
残念ながら、scriptファイルにDelete/accountリクエストが含まれていて、ページを開くとすぐにユーザーのアカウントが削除されてしまいました。
このような予期せぬ事故を防ぎ、
セキュリティを強化するため
、他のソースからのアクセスを防ぐポリシーが登場しました。同一原産地政策 (Same-Origin Policy)
そのため、同じソースからしかリソースを共有できないというポリシーを使うようになりました。
ここで、同じソースとは、
クライアントとサーバーが同じソース
にある場合は同じソースであり、別のサーバーにある場合は別のソースとして扱います。
例えば、上の写真でdomain-a.comのユーザーがdomain-b.comのサーバーにリクエストすると、ホストが違うので、他のソースにリクエストした状態です。
ドメイン以外にも同じプロジェクト内で定義されたcssファイルに対するリクエストは同一ソースリクエストであり、フォントの場合、googleのような外部サイトからリソースを取得する場合は別のソースリクエストと言えます。
しかし、このように厳密にブロックしてしまえば、好きなページを作ることができるのでしょうか🤔?
オープンなインターネット環境では、他のソースからリソースを取り込んで使用することはよくあることです。
そのため、いくつかの例外規定を設け、
他のソースからのリソースを許可するポリシー
が登場しました。それは、
CORSのポリシーを守ったリソースリクエスト
です!その他のソースポリシー
実際、私たちを悩ませた
CORS
の真っ赤なエラーメッセージは、他のソースからリソースを取得するための解決策でした。同一ソースポリシー(SOP)に違反しても
CORS
のポリシーを守れば、他のソースのリソースも呼び出すことができるようになるのです!では、どのように
CORS
エラーを解決することができるのでしょうか?まず、ブラウザでのCORS
の動作過程について説明します。
1.クライアントからHTTPリクエストのヘッダーにOriginを入れ、転送

Webはサーバーにリクエストを送る際にHTTPプロトコルを利用します。
このとき
"ここから来ました"
を表す Origin
という値をリクエストヘッダに載せて送ります。2.サーバーは応答ヘッダにAccess-Control-Allow-Originを入れ、クライアントに転送

サーバーはリクエストを受け取った後、クライアントにこの
「このURLはリソースにアクセスできますよ」
をAccess-Control-Allow-Origin
フィールドに入れて応答します。3.クライアントからの応答を比較し、ブロックの可否を決定します。
ブラウザは自分が送ったリクエストのOriginとサーバーが送ったAccess-Control-Allow-Originの値を比較して、応答を使うかどうかを判断します。
もし
一致しない場合
、応答を使用せずに破棄し、このような状況がCORSエラー
に該当します。CORSの設定方法と注意点
AJAXリクエストにおける認証情報の扱い方
- 通常、AJAXリクエストでは認証情報(クッキー、認証ヘッダー、TLSクライアント証明書など)が自動的に含まれません。
- 認証情報を含むAJAXリクエストを送信するには、特定の設定が必要です。
withCredentials
とcredentials
引数の設定
- XMLHttpRequestを使用する場合:
withCredentials
引数をtrue
に設定します。これにより、ブラウザはクロスオリジンリクエストにクッキーや認証ヘッダーを含めるようになります。
- Fetch APIを使用する場合:
credentials
引数をinclude
に設定します。これにより、クロスオリジンリクエストにも認証情報が含まれるようになります。
CORS設定でのオリジン指定の重要性
- 認証情報を含むリクエストをAPIサーバーに送信する場合、サーバーは
Access-Control-Allow-Credentials: true
ヘッダーを含む応答を返します。
- クライアントは、このヘッダーが応答に含まれていない場合、リクエストを拒否します。
- セキュリティ上の理由から、APIサーバーでCORS Credentialを許可する場合、オリジンを具体的に指定する必要があります。ワイルドカード(
*
)は使用できません。
結論
CORS
問題はウェブ開発で頻繁に直面する課題の一つです。この記事を通じて、CORS
設定の重要性と適切な設定方法を理解し、将来的なCORS
エラーに効果的に対応できるようになることを願っています。
댓글