From 7c9370ef904c7b977229310446d14c13e45c0a02 Mon Sep 17 00:00:00 2001 From: aecra Date: Sun, 26 Jun 2022 01:28:33 +0800 Subject: [PATCH] feat: add CORS filter to fix OPTION request failure (#826) --- main.go | 1 + object/application.go | 37 +++++++++++++++++++++++++++++++++++++ routers/cors_filter.go | 31 +++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 routers/cors_filter.go diff --git a/main.go b/main.go index c6a81ba3..275e223a 100644 --- a/main.go +++ b/main.go @@ -51,6 +51,7 @@ func main() { // https://studygolang.com/articles/2303 beego.InsertFilter("*", beego.BeforeRouter, routers.StaticFilter) beego.InsertFilter("*", beego.BeforeRouter, routers.AutoSigninFilter) + beego.InsertFilter("*", beego.BeforeRouter, routers.CorsFilter) beego.InsertFilter("*", beego.BeforeRouter, routers.AuthzFilter) beego.InsertFilter("*", beego.BeforeRouter, routers.RecordMessage) diff --git a/object/application.go b/object/application.go index 3fd88ebf..49826c5f 100644 --- a/object/application.go +++ b/object/application.go @@ -16,6 +16,7 @@ package object import ( "fmt" + "net/url" "strings" "github.com/casdoor/casdoor/util" @@ -319,3 +320,39 @@ func CheckRedirectUriValid(application *Application, redirectUri string) bool { } return validUri } + +func IsAllowOrigin(origin string) bool { + allowOrigin := false + originUrl, err := url.Parse(origin) + if err != nil { + return false + } + + rows, err := adapter.Engine.Cols("redirect_uris").Rows(&Application{}) + if err != nil { + panic(err) + } + + application := Application{} + for rows.Next() { + err := rows.Scan(&application) + if err != nil { + panic(err) + } + for _, tmpRedirectUri := range application.RedirectUris { + u1, err := url.Parse(tmpRedirectUri) + if err != nil { + continue + } + if u1.Scheme == originUrl.Scheme && u1.Host == originUrl.Host { + allowOrigin = true + break + } + } + if allowOrigin { + break + } + } + + return allowOrigin +} diff --git a/routers/cors_filter.go b/routers/cors_filter.go new file mode 100644 index 00000000..207d9157 --- /dev/null +++ b/routers/cors_filter.go @@ -0,0 +1,31 @@ +package routers + +import ( + "net/http" + + "github.com/astaxie/beego/context" + "github.com/casdoor/casdoor/object" +) + +const ( + headerOrigin = "Origin" + headerAllowOrigin = "Access-Control-Allow-Origin" + headerAllowMethods = "Access-Control-Allow-Methods" + headerAllowHeaders = "Access-Control-Allow-Headers" +) + +func CorsFilter(ctx *context.Context) { + if ctx.Input.Method() == "OPTIONS" { + origin := ctx.Input.Header(headerOrigin) + + if object.IsAllowOrigin(origin) { + ctx.Output.Header(headerAllowOrigin, origin) + ctx.Output.Header(headerAllowMethods, "POST, GET, OPTIONS") + ctx.Output.Header(headerAllowHeaders, "Content-Type, Authorization") + ctx.ResponseWriter.WriteHeader(http.StatusOK) + } else { + ctx.ResponseWriter.WriteHeader(http.StatusForbidden) + } + return + } +}