APIサーバーを構築する際にGo+Ginを使う場合、まずはCORSの設定を適切に行う必要があります。
例えばJavaScriptでAPIにアクセスしたとき、以下のようなエラーが表示されているとき、CORSの設定が不足しています。
Access to XMLHttpRequest at 'http://xxxxxx/v1/zzzz' from origin 'http://xxxxxx ' has been blocked by CORS policy: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.
今回はこの状況を解消する方法を解説しています。
結論
主にサーバーサイド(Gin)の設定追加が必要です。
Gin のCORSミドルウェアをインストール
$ go get github.com/gin-contrib/cors
main.go に以下を追加
import "github.com/gin-contrib/cors"
func main() {
r := gin.Default()
// CORS 対応
config := cors.DefaultConfig()
config.AllowOrigins = []string{
"http://example.com",
}
r.Use(cors.New(config))
r.Run(":8080")
}
実行環境
# go version
go version go1.16.4 linux/amd64
# go list -m github.com/gin-gonic/gin
github.com/gin-gonic/gin v1.7.2
CORSエラーとは何か
あるサイトのJavaScriptなどから他のドメインのリソース(APIなど)にアクセスするにはCORS(Cross Origin Resource Sharing)の許可をする必要があります。
オリジン(Origin)とは、ドメインとポートの組み合わせたエンドポイントを指します(e.g. http://example.com:8080)
つまり、CORSとは、元のサイトとは異なるオリジンにあるリソースの利用(アクセス)を意味します。
CORS policyは、他のサーバーから情報を抜き取られたり、任意のスクリプトを実行されるのを防ぐ、セキュリティの仕組みです。
JavaScriptはデフォルト状態で他のオリジンのリソースへのアクセスは許可しません。なので、デフォルトのCORS policyでは、他のオリジン(APIなど)にアクセスしようとするとエラーとなるわけです。
開発中に
Access...from origin...has been blocked by CORS policy...
のエラーが出るときにはCORSの設定が正しく行われていません。
CORS設定の一覧
CORSの設定は主にサーバーサイド(API)で行います。
クライアントサイドについてはそもそも設定が不要な場合と、CORSを許容する設定を追加する場合があります。お使いのクライアント(XMLHttpRequest、Fetch APIなど)に合わせて設定してください。
Ginでは次のように設定します。いずれもドキュメントにあるのと同じです。
オリジンを許可する
cors.DefaultConfig()
はlocalhostのみを許容するデフォルト設定を返します。
config.AllowOrigins
に許可したいオリジンを配列形式で設定します。
import (
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
config := cors.DefaultConfig()
config.AllowOrigins = []string{
"http://example.com",
}
r.Use(cors.New(config))
r.Run(":8080")
}
全てのオリジンを許可する
環境によってはすべてのオリジンを許可する必要があります。
config.AllowAllOrigins = true
とすれば問題ありません。
func main() {
r := gin.Default()
config := cors.DefaultConfig()
config.AllowAllOrigins = true
r.Use(cors.New(config))
r.Run(":8080")
}
許可するヘッダーを指定する
場合によって認証ヘッダーを許可する必要に迫られます。
config.AllowHeaders
に配列で設定します。
func main() {
r := gin.Default()
config := cors.DefaultConfig()
config.AllowAllOrigins = true
config.AllowHeaders = []string{"origin", "authorization"}
r.Use(cors.New(config))
r.Run(":8080")
}
今回参考にしたページ・資料
gin-contrib/cors: Official CORS gin's middleware