背景
こんにちは。エンジニアのKennieです!
開発をしていた際にフロントエンドからバックエンドにリクエストを送る必要がありましたが、リクエストがうまく処理されず、送信されていませんでした。調べていくと、CORSの設定を適切に行うことで問題を解決できたので、そこで学んだことをまとめようと思います!
リクエストが処理されなかった原因
開発をしていた際にリクエスト処理がされなかった原因は、同一オリジンポリシーの制限によるものでした。同一オリジンとは、プロトコル、ドメイン、ポート番号がすべて同じであることを指します。同一オリジンポリシーは、上記3つのいずれかが異なれば、異なるオリジン間でのリソースアクセスを制限する仕組みです。今回の開発では、フロントエンドがポート9000、バックエンドがポート3000を使っていたため、制限を受け、リクエストが送信されませんでした。この際にCORSという仕組みを使ってリソースアクセスの制限を解除し、リクエストを送信することができました。
CORSとは
CORSとは異なるオリジン間でのリソース共有を許可する仕組みです。CORSを適切に設定することで同一オリジンポリシーによるリソースへのアクセスの制限を解除することができます。今回の開発ではオリジン、メソッド、ヘッダーの制限がかかっていたので、そちらの解除をしました。
func EnableCORS(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "http://localhost:3000")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
if r.Method == http.MethodOptions {
w.WriteHeader(http.StatusOK)
return
}
next.ServeHTTP(w, r)
})
}
オリジンの制限の解除
w.Header().Set("Access-Control-Allow-Origin", "http://localhost:3000)
どのオリジンにアクセスできるかを指定、localhost:3000からのアクセスを許可しています。
メソッドの制限の解除
w.Header().Set("Access-Control-Allow-Origin","GET, POST, PUT, DELETE, OPTIONS")
どのメソッドにアクセスできるかを指定、GET, POST, PUT, DELETE, OPTIONSのメソッドのアクセスを許可しています。
ヘッダーの制限の解除
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
どのヘッダーにアクセスできるかを指定、Content-Typeのヘッダーを許可しています。
オリジンと、メソッドと、ヘッダーの規制の解除をしたことによってブラウザからのリクエストを送信することができました。
なお、今回の実装では、プリフライトリクエストを通じてCORSの規制を緩和しました。
プリフライトリクエストとは
実際のリクエストを送信する前に、OPTIONSリクエストを送信し、そのリクエストが許可されているかどうかを確認する仕組みです。安全性が確認されていないHTTPメソッドやカスタムヘッダー、特定のContent-Typeを含む場合に使用されます。これにより、サーバーとクライアントの間で安全な通信を保証します。
プリフライトリクエスト(OPTIONS)が発生するのは、具体的には以下の条件に該当するときです。
1. HTTPメソッドが制限外のもの
以下に該当しないメソッドを追加した場合:
GET
,HEAD
, POST
2. カスタムヘッダーが含まれる場合
以下に該当しないカスタムヘッダーを追加した場合:
Accept
, Accept-Language
,Content-Language
,Content-Type
3. Content-Type が特定の値以外
以下に該当しないContent-Typeを使用した場合
application/x-www-form-urlencoded
multipart/form-data
text/plain
4. リクエストがクロスオリジンである場合
上記のいずれかの条件を満たしている場合に限り、クロスオリジンリクエストでプリフライトが発生します。
今回の開発ではこれらの条件に当てはまるリソースを使用していたので、プリフライトが発生していました。
まとめ
今回の開発では、CORSを設定することでリクエストの送信を可能にしました。具体的には、オリジン、メソッド、ヘッダーの制限を緩和し、ブラウザからのリクエストを送信できるようにしました。また、CORS設定に加え、プリフライトリクエストについての理解を深めることができました。