APIとして使用される場合を想定
近年SPAサイトがよく作られており、サーバサイドの言語はAPIとして開発されることが多いでしょう。
APIとして使用する場合、注意しなくてはいけないのがクロスオリジンの設定です。
他サイトから自由自在にアクセスされてしまえば、セキュリティ的にアウトですしDos攻撃の餌食にもなってしまいます。
なので、APIへのアクセスを許可するサイトURL、メソッド(POSTやGET)、ヘッダー情報を予め設定しておきましょう。
GinのGors設定
まずは必要なモジュールをインストールします。
go get github.com/gin-contrib/cors
あとは以下のように「r.Use(cors.New(cors.Config{}...」と設定値を入力するだけで良いのです。
以下はあくまでサンプルですが、内容についてはコメントを入れていきます。
package main import ( "github.com/gin-gonic/gin" "github.com/gin-contrib/cors" "time" ) func main() { r := gin.Default() // ここからCorsの設定 r.Use(cors.New(cors.Config{ // アクセスを許可したいアクセス元 AllowOrigins: []string{ 'https://example.com', 'https://example2.com', }, // アクセスを許可したいHTTPメソッド(以下の例だとPUTやDELETEはアクセスできません) AllowMethods: []string{ "POST", "GET", "OPTIONS", }, // 許可したいHTTPリクエストヘッダ AllowHeaders: []string{ "Access-Control-Allow-Credentials", "Access-Control-Allow-Headers", "Content-Type", "Content-Length", "Accept-Encoding", "Authorization", }, // cookieなどの情報を必要とするかどうか AllowCredentials: true // preflightリクエストの結果をキャッシュする時間 MaxAge: 24 * time.Hour, })) r.GET("/", func(c *gin.Context) { c.String(200, "Hello,World!") }) r.POST("/api/test", controller.TestMethod) r.Run(":9000") }
上記以外にも様々な設定情報があるので、詳細は以下をご覧ください。
https://godoc.org/github.com/gin-contrib/cors#Config
許可されないアクセスがされた場合
ではアクセスが許可されていないサイトからアクセスされた場合、どのようなレスポンスが返ってくるのでしょうか。
実際にcurlコマンドでアクセスをして色々試してもらいたいのですが、403が返ってきます。(gin-contrib/corsの仕様)
エラーコード403の意味はご存知ですか?
はい、アクセス禁止という意味です。
不正なアクセスに対してはしっかりブロックできていますね。
CORS 対応の後にルーティングを書かないとうまく動かない
注意点ですが、以下のようにルーティングをCors設定の前に書かないように注意してください。
package main import ( "github.com/gin-gonic/gin" "github.com/gin-contrib/cors" "time" ) func main() { r := gin.Default() // ルーティングがCors設定の前に書かれている r.GET("/", func(c *gin.Context) { c.String(200, "Hello,World!") }) r.POST("/api/test", controller.TestMethod) r.Use(cors.New(cors.Config{ AllowOrigins: []string{ 'https://example.com', 'https://example2.com', }, AllowMethods: []string{ "POST", "GET", "OPTIONS", }, AllowHeaders: []string{ "Access-Control-Allow-Credentials", "Access-Control-Allow-Headers", "Content-Type", "Content-Length", "Accept-Encoding", "Authorization", }, AllowCredentials: true MaxAge: 24 * time.Hour, })) r.Run(":9000") }
これだとCorsの制御に入る前にルーティング先に遷移してしまうためか上手くいきません。
必ずルーティングの前にCorsの制御を書くように注意してください。