オートコープスプリフライトハンドルウィッシュゴリラ
19623 ワード
導入
最近のビッグバックエンドソリューションは、一般的に相互に相互作用する1つ以上のフロントエンド(一般的にブラウザ)アプリケーションのセットのように見えます.
これらのサービスは、複数の仮想または物理的なマシン間で分散され、結果として、あらゆるアプリケーション(アプリケーションをホストするサーバーを意味する)は、異なるドメイン名/IPアドレスを取得します.
フロントエンドアプリケーションは、通常、バックエンドと対話するためにJavaScriptまたはTypesScriptを使用しますが、要求が異なる(フロントエンドサーバから)サーバーに行くなら、ブラウザは、それがセキュリティに潜在的危険を冒して、それをブロックすると仮定するかもしれません.この問題を解決するために、バックエンドAPIは有効な起源(フロントエンドアプリケーションがあるドメイン名またはIP)でヘッダーを提供しなければなりません.今日私たちはどのように適切にセットアップGorilla/MUXのWeb APIを永遠にCorsを忘れることを学ぶつもりです.
バックエンドから何を提供すべきか
以下のRESTリソースを考えます.
GET /api/user/
- すべてのユーザーを得るGET /api/user/{id}/
- シングルユーザを取得するにはPOST /api/user/
- 新規ユーザーの作成PUT /api/user/{id}/
- 既存のユーザーDELETE /api/user/{id}/
- 既存の削除OPTIONS /api/user/
and OPTIONS /api/user/{id}/
次のヘッダを指定します.Access-Control-Allow-Origin
- ドメイン名/IPまたは由来
Access-Control-Allow-Headers
- ここで簡単に設定できますAccess-Control-Allow-Methods
- 我々は、単にすべてのリストをしかし、送信する方が良いと思います
OPTIONS,
GET, POST
値として/api/user/
and OPTIONS, GET,
PUT, DELETE
for /api/user/{id}/
; github.com\gorilla\handlers
. それは、特定の起源だけにアクセスを制限するミドルウェアを持っています.オプションのリクエストがブラウザによって送信されていないため、バックエンドはオプションのリクエストに応答する必要はないことに注意してくださいsimple requests . しかし上記の例ではこれをしなければなりません.あなたのAPIがかなり大きいときには、常にあなたがちょうどいくつかの複雑なエンドポイントの設計を終えているときに、それを行うことを忘れてしまうことができます.( wissance LLC )ソリューションの使用open source github package ) あなたは前フライトハンドラを追加することを忘れることができますour package これは自動的に行います.あなたが私たちのパッケージがあなたのために有用であることを見つけたら、私たちに星をください.簡単にすべての作品を作る方法
我々は、我々自身を実行しました
HandlerFunc
それに似ているmux.Router.HandlerFunc
しかし、いくつかの小さな違いでmux.Router
最初のパラメータとして.我々は、サブルータで働く必要があるので、我々はこれをしましたthis unit test あなたは参照を使用することができます..Methods()
ルートハンドラーを割り当てるとき、我々はこれもものをより単純にすると思います.WebApiHandler
インスタンスとその2番目の引数として必要な原点値を渡しますAccess-Control-Allow-Origin
ヘッダは1つの値のみをサポートし、HandlerFunc
Gorilla/muxの代わりに、例を見てください. handler := NewWebApiHandler(true, AnyOrigin)
// Get only method
baseUrl := "http://127.0.0.1:8998"
configResource := baseUrl + "/api/config/"
handler.HandleFunc(handler.Router, configResource,
webApi.GetConfigHandler,"GET")
// full crud
functionResourceRoot := baseUrl + "/api/function/"
handler.HandleFunc(handler.Router, functionResourceRoot,
webApi.GetAllFunctions, "GET")
handler.HandleFunc(handler.Router, functionResourceRoot,
webApi.CreateFunction, "POST")
functionResourceById := baseUrl + "/api/function/{id:[0-9]+}/"
handler.HandleFunc(handler.Router, functionResourceById,
webApi.GetFunctionById, "GET")
handler.HandleFunc(handler.Router, functionResourceById,
webApi.UpdateFunction, "PUT")
handler.HandleFunc(handler.Router, functionResourceById,
webApi.DeleteFunction, "DELETE")
上のスニペットでは、3つの追加のプリフライトハンドラを追加する必要があります.http://127.0.0.1:8998/api/config/
; http://127.0.0.1:8998/api/function/
; http://127.0.0.1:8998/api/function/{id}
; router.HandleFunc(functionResourceRoot,
webApi.PreflightRoot).Methods("OPTIONS")
router.HandleFunc(functionResourceById,
webApi.PreflightByID).Methods("OPTIONS")
func (webApi *WebApiContext) PreflightRoot(respWriter http.ResponseWriter, request *http.Request) {
rest.EnableCors(&respWriter)
respWriter.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
}
func (webApi *WebApiContext) PreflightByID(respWriter http.ResponseWriter, request *http.Request) {
rest.EnableCors(&respWriter)
respWriter.Header().Set("Access-Control-Allow-Methods", "GET, PUT, DELETE, OPTIONS")
}
また、何を表示する必要がありますwebApi
オブジェクトとそのリクエストハンドラ関数のいくつかは以下のようになります.type WebApiContext struct {
Db *gorm.DB // passing gorm to Context
Config *config.AppConfig
// other fields
}
func (webApi *WebApiContext) GetAllFunctions(respWriter http.ResponseWriter, request *http.Request) {
// return here array of functions, body omitted
}
func (webApi *WebApiContext) GetFunctionById(respWriter http.ResponseWriter, request *http.Request) {
// return function by id, body omitted
}
ライブラリを追加した後、どうやってコードが変わったかを見てみましょう. webApi := rest.WebApiContext{Db: appContext.ModelContext.Context, Config: appContext.Config, WebApiHandler: gr.NewWebApiHandler(true, gr.AnyOrigin)}
webApi.WebApiHandler.Router.Use( keycloakAuthService.KeycloakAuthMiddleware)
webApi.WebApiHandler.Router.Use(r.InspectorMiddleware)
router := webApiContext.WebApiHandler.Router
router.StrictSlash(true)
// function resource
webApi.WebApiHandler.HandleFunc(router, baseUri+"/function/", webApi.GetAllFunctions, "GET")
webApi.WebApiHandler.HandleFunc(router, baseUri+"/function/find/", webApi.FindFunctions, "GET").Queries("query", "{query}")
webApi.WebApiHandler.HandleFunc(router, baseUri+"/function/name/", webApi.GetFunctionsNames, "GET")
webApi.WebApiHandler.HandleFunc(router, baseUri+"/function/{id:[0-9]+}/", webApi.GetFunctionById, "GET")
webApi.WebApiHandler.HandleFunc(router, baseUri+"/function/{id:[0-9]+}/body/", webApi.GetFunctionWithBodyById, "GET")
webApi.WebApiHandler.HandleFunc(router, baseUri+"/function/", webApi.CreateFunction, "POST")
webApi.WebApiHandler.HandleFunc(router, baseUri+"/function/{id:[0-9]+}/", webApi.UpdateFunction, "PUT")
webApi.WebApiHandler.HandleFunc(router, baseUri+"/function/{id:[0-9]+}/", webApi.DeleteFunction, "DELETE")
webApi.WebApiHandler.HandleFunc(router, baseUri+"/function/filter/", webApi.FilterFunctions, "GET")
結論
私たちはこのパッケージを作ったのですが、私たちは手に余暇をたくさん持っているからではありませんが、大量のCors関連のエラーのために私たちはそれをすることを強いられました.私たちがこの解決策を持っている今、Corsはもはや問題ではありません.
Reference
この問題について(オートコープスプリフライトハンドルウィッシュゴリラ), 我々は、より多くの情報をここで見つけました https://dev.to/evillord666/auto-cors-preflight-handle-wih-gorillamux-and-go-855テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol