diff --git a/go.mod b/go.mod index 3d3be444..6f578ca0 100644 --- a/go.mod +++ b/go.mod @@ -13,14 +13,20 @@ require ( github.com/stripe/stripe-go/v74 v74.22.0 github.com/zeromicro/go-zero v1.5.2 golang.org/x/image v0.0.0-20190802002840-cff245a6509b + golang.org/x/oauth2 v0.10.0 gorm.io/driver/mysql v1.5.1 gorm.io/gorm v1.25.1 ) require ( + cloud.google.com/go/compute v1.20.1 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect github.com/andybalholm/brotli v1.0.5 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/schollz/progressbar v1.0.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect ) require ( @@ -68,11 +74,11 @@ require ( go.opentelemetry.io/otel/trace v1.14.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/automaxprocs v1.5.2 // indirect - golang.org/x/net v0.9.0 // indirect - golang.org/x/sys v0.7.0 // indirect - golang.org/x/text v0.9.0 - google.golang.org/genproto v0.0.0-20230123190316-2c411cf9d197 // indirect - google.golang.org/grpc v1.54.0 // indirect - google.golang.org/protobuf v1.30.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect + golang.org/x/net v0.12.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/text v0.11.0 + google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc // indirect + google.golang.org/grpc v1.55.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect + gopkg.in/yaml.v2 v2.4.0 ) diff --git a/go.sum b/go.sum index 75e8aa35..202f71cb 100644 --- a/go.sum +++ b/go.sum @@ -19,6 +19,10 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg= +cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= @@ -105,8 +109,8 @@ github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzq github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -353,14 +357,16 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= -golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= +golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -405,8 +411,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= -golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -419,8 +425,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -491,6 +497,8 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -522,8 +530,12 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20230123190316-2c411cf9d197 h1:BwjeHhu4HS48EZmu1nS7flldBIDPC3qn+HqaSQ1K4x8= -google.golang.org/genproto v0.0.0-20230123190316-2c411cf9d197/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc h1:8DyZCyvI8mE1IdLy/60bS+52xfymkE72wv1asokgtao= +google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= +google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc h1:kVKPf/IiYSBWEWtkIn6wZXwWGCnLKcC8oWfZvXjsGnM= +google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -540,8 +552,8 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= -google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -555,8 +567,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/proxyserver/get_zero_Info.go b/proxyserver/get_zero_Info.go index db74dc77..a90ad753 100644 --- a/proxyserver/get_zero_Info.go +++ b/proxyserver/get_zero_Info.go @@ -10,11 +10,13 @@ import ( "gopkg.in/yaml.v2" ) +// Config 结构体用于解析yaml配置文件 type Config struct { Host string `yaml:"Host"` Port int `yaml:"Port"` } +// Result 结构体用于存储解析结果 type Result struct { FolderName string Host string @@ -22,6 +24,7 @@ type Result struct { PrefixRoute map[string]bool } +// GetZeroInfo 遍历指定目录,并解析相关信息 func GetZeroInfo(rootDir string) (results []*Result) { entries, err := ioutil.ReadDir(rootDir) if err != nil { @@ -29,21 +32,21 @@ func GetZeroInfo(rootDir string) (results []*Result) { } for _, entry := range entries { + // 只处理目录类型 if entry.IsDir() { - result, err := findFoldersAndExtractInfo(rootDir, entry) if err != nil { log.Fatal(err) } results = append(results, result) - } } return } +// findFoldersAndExtractInfo 查找目录并提取信息 func findFoldersAndExtractInfo(rootDir string, entry os.FileInfo) (*Result, error) { var result *Result @@ -55,6 +58,7 @@ func findFoldersAndExtractInfo(rootDir string, entry os.FileInfo) (*Result, erro return err } + // 跳过非目录类型 if !info.IsDir() { return nil } @@ -64,10 +68,12 @@ func findFoldersAndExtractInfo(rootDir string, entry os.FileInfo) (*Result, erro return err } + // 跳过非当前目录的子目录 if strings.Contains(relPath, string(os.PathSeparator)) { return filepath.SkipDir } + // 读取配置文件 configPath := filepath.Join(path, "etc", folderName+".yaml") routesPath := filepath.Join(path, "internal", "handler", "routes.go") @@ -82,6 +88,7 @@ func findFoldersAndExtractInfo(rootDir string, entry os.FileInfo) (*Result, erro return err } + // 读取路由文件 routesContent, err := ioutil.ReadFile(routesPath) if err != nil { return err @@ -89,6 +96,7 @@ func findFoldersAndExtractInfo(rootDir string, entry os.FileInfo) (*Result, erro PrefixRoute := extractPrefixRouteValues(string(routesContent)) + // 构建结果 result = &Result{ FolderName: folderName, Host: config.Host, @@ -106,11 +114,13 @@ func findFoldersAndExtractInfo(rootDir string, entry os.FileInfo) (*Result, erro return result, nil } +// extractPrefixRouteValues 提取路由前缀 func extractPrefixRouteValues(content string) map[string]bool { lines := strings.Split(content, "\n") var prefixPath map[string]bool = make(map[string]bool) for _, line := range lines { + // 查找包含 "Path:" 的行 if strings.Contains(line, "Path:") { path := strings.TrimSpace(strings.TrimPrefix(line, "Path:")) paths := strings.Split(strings.Trim(path, `"`), "/") diff --git a/proxyserver/main.go b/proxyserver/main.go index 667863b0..5534ee1c 100644 --- a/proxyserver/main.go +++ b/proxyserver/main.go @@ -13,8 +13,10 @@ import ( "time" ) +// Backend结构体 var Backends []*Backend +// 设置跨域请求 func SetCors(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE") @@ -29,9 +31,11 @@ func SetCors(w http.ResponseWriter, r *http.Request) { } } +// 存储路径的并发安全的Map var pathdict sync.Map = sync.Map{} func main() { + // 将静态资源路径存储到pathdict pathdict.Store("/css", true) pathdict.Store("/fonts", true) pathdict.Store("/img", true) @@ -39,7 +43,7 @@ func main() { pathdict.Store("/svg", true) pathdict.Store("/favicon.ico", true) - rootDir := "../server" // Change this to your root directory + rootDir := "../server" // 更改为你的根目录 vueBuild := "/opt/fusenpack-vue-created" apiURL, err := url.Parse("http://localhost:9900") if err != nil { @@ -48,6 +52,7 @@ func main() { mux := http.NewServeMux() + // 获取并解析服务信息 results := GetZeroInfo(rootDir) var allRoutes map[string]bool = make(map[string]bool) @@ -59,20 +64,23 @@ func main() { allRoutes[k] = true } + // 根据获取的服务信息创建后端服务 Backends = append(Backends, NewBackend(mux, fmt.Sprintf("http://%s:%d", result.Host, result.Port), routes...)) } - // Define the static file server that serves the Vue dist folder + // 定义用于服务Vue dist文件夹的静态文件服务器 fs := http.FileServer(http.Dir(vueBuild)) indexHtmlPath := vueBuild + "/index.html" mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if strings.HasPrefix(r.URL.Path, "/api") { + // 对/api开头的请求进行反向代理 proxy := httputil.NewSingleHostReverseProxy(apiURL) proxy.ServeHTTP(w, r) } else { + // 根据请求路径判断是服务静态文件或者是返回index.html idx := strings.Index(r.URL.Path[1:], "/") var prefix string if idx != -1 { @@ -95,6 +103,7 @@ func main() { log.Fatal(http.ListenAndServe(ServerAddress, mux)) } +// 后端服务的类型 type Backend struct { HttpAddress string Client *http.Client @@ -102,7 +111,7 @@ type Backend struct { } func NewBackend(mux *http.ServeMux, httpAddress string, muxPaths ...string) *Backend { - + // 如果路径最后没有以'/'结尾,则添加'/' for i, muxPath := range muxPaths { if muxPath[len(muxPath)-1] != '/' { muxPath = muxPath + "/" @@ -110,6 +119,7 @@ func NewBackend(mux *http.ServeMux, httpAddress string, muxPaths ...string) *Bac } } + // 创建HTTP客户端,设置相关的超时参数和连接数限制 client := &http.Client{ Transport: &http.Transport{ DialContext: (&net.Dialer{ @@ -125,23 +135,22 @@ func NewBackend(mux *http.ServeMux, httpAddress string, muxPaths ...string) *Bac }, } + // 创建后端服务对象,包含地址和客户端 backend := &Backend{ HttpAddress: httpAddress, Client: client, } + // 创建处理请求的函数 handleRequest := func(w http.ResponseWriter, r *http.Request) { + // 解析目标URL,包含了查询参数 targetURL, err := url.Parse(httpAddress + r.URL.Path) if err != nil { http.Error(w, "Error parsing target URL", http.StatusInternalServerError) return } - // hasBridge := strings.Contains(r.Header.Get("Access-Control-Request-Headers"), "bridge") - - // 解析目标URL时已经包含了查询参数 - targetURL.RawQuery = r.URL.RawQuery - + // 创建新的请求 proxyReq, err := http.NewRequest(r.Method, targetURL.String(), r.Body) if err != nil { http.Error(w, "Error creating proxy request", http.StatusInternalServerError) @@ -159,6 +168,7 @@ func NewBackend(mux *http.ServeMux, httpAddress string, muxPaths ...string) *Bac proxyReq.ContentLength = r.ContentLength proxyReq.Header.Set("Content-Type", r.Header.Get("Content-Type")) + // 发送请求 resp, err := backend.Client.Do(proxyReq) if err != nil { http.Error(w, "Error sending proxy request", http.StatusInternalServerError) @@ -173,10 +183,6 @@ func NewBackend(mux *http.ServeMux, httpAddress string, muxPaths ...string) *Bac } } - // if hasBridge { - // w.Header().Add("Access-Control-Allow-Headers", "Bridge") - // } - // 转发目标服务器的响应状态码和主体 w.WriteHeader(resp.StatusCode) _, err = io.Copy(w, resp.Body) @@ -186,9 +192,11 @@ func NewBackend(mux *http.ServeMux, httpAddress string, muxPaths ...string) *Bac } } + // 为每个路径注册处理函数 for _, muxPath := range muxPaths { mux.HandleFunc(muxPath, handleRequest) } + // 返回后端服务对象 return backend } diff --git a/server/home-user-auth/etc/home-user-auth.yaml b/server/home-user-auth/etc/home-user-auth.yaml index 6490fea2..462805ce 100644 --- a/server/home-user-auth/etc/home-user-auth.yaml +++ b/server/home-user-auth/etc/home-user-auth.yaml @@ -8,5 +8,13 @@ Auth: AccessExpire: 2592000 RefreshAfter: 1592000 +OAuth: + - name: google + appid: 1064842923358-e94msq2glj6qr4lrva9ts3q8h.apps.googleusercontent.com + secret: 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 + + - name: facebook + appid: 1095953604597065 + secret: b146872550a190d5275b1420c212002e Stripe: - SK: "sk_test_51IisojHygnIJZeghPVSBhkwySfcyDV4SoAduIxu3J7bvSJ9cZMD96LY1LO6SpdbYquLJX5oKvgEBB67KT9pecfCy00iEC4pp9y" + SK: sk_test_51IisojHygnIJZeghPVSBhkwySfcyDV4SoAduIxu3J7bvSJ9cZMD96LY1LO6SpdbYquLJX5oKvgEBB67KT9pecfCy00iEC4pp9y diff --git a/server/home-user-auth/internal/config/config.go b/server/home-user-auth/internal/config/config.go index 44f26567..9d09c058 100644 --- a/server/home-user-auth/internal/config/config.go +++ b/server/home-user-auth/internal/config/config.go @@ -6,11 +6,19 @@ import ( "github.com/zeromicro/go-zero/rest" ) +type OAuth struct { + Name string `json:"name"` + Appid string `json:"appid"` + Secret string `json:"secret"` +} + type Config struct { rest.RestConf SourceMysql string Auth types.Auth + OAuth []OAuth + Stripe struct { SK string } diff --git a/server/home-user-auth/internal/handler/routes.go b/server/home-user-auth/internal/handler/routes.go index 718c8455..c0b3b4e7 100644 --- a/server/home-user-auth/internal/handler/routes.go +++ b/server/home-user-auth/internal/handler/routes.go @@ -67,6 +67,16 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/api/user/order-delete", Handler: UserOderDeleteHandler(serverCtx), }, + { + Method: http.MethodPost, + Path: "/api/user/oauth2/login/google", + Handler: UserGoogleLoginHandler(serverCtx), + }, + { + Method: http.MethodPost, + Path: "/api/user/oauth2/login", + Handler: UserOAuth2LoginHandler(serverCtx), + }, }, ) } diff --git a/server/home-user-auth/internal/handler/usergoogleloginhandler.go b/server/home-user-auth/internal/handler/usergoogleloginhandler.go new file mode 100644 index 00000000..934eebeb --- /dev/null +++ b/server/home-user-auth/internal/handler/usergoogleloginhandler.go @@ -0,0 +1,78 @@ +package handler + +import ( + "errors" + "net/http" + + "github.com/zeromicro/go-zero/core/logx" + "github.com/zeromicro/go-zero/rest/httpx" + + "fusenapi/utils/auth" + "fusenapi/utils/basic" + + "fusenapi/server/home-user-auth/internal/logic" + "fusenapi/server/home-user-auth/internal/svc" + "fusenapi/server/home-user-auth/internal/types" +) + +func UserGoogleLoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + + var ( + // 定义错误变量 + err error + // 定义用户信息变量 + userinfo *auth.UserInfo + ) + // 解析JWT token,并对空用户进行判断 + claims, err := svcCtx.ParseJwtToken(r) + // 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &basic.Response{ + Code: 401, // 返回401状态码,表示未授权 + Message: "unauthorized", // 返回未授权信息 + }) + logx.Info("unauthorized:", err.Error()) // 记录错误日志 + return + } + + if claims != nil { + // 从token中获取对应的用户信息 + userinfo, err = auth.GetUserInfoFormMapClaims(claims) + // 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &basic.Response{ + Code: 401, + Message: "unauthorized", + }) + logx.Info("unauthorized:", err.Error()) + return + } + } else { + // 如果claims为nil,则认为用户身份为白板用户 + userinfo = &auth.UserInfo{UserId: 0, GuestId: 0} + } + + var req types.RequestGoogleLogin + // 如果端点有请求结构体,则使用httpx.Parse方法从HTTP请求体中解析请求数据 + if err := httpx.Parse(r, &req); err != nil { + httpx.OkJsonCtx(r.Context(), w, &basic.Response{ + Code: 510, + Message: "parameter error", + }) + logx.Info(err) + return + } + // 创建一个业务逻辑层实例 + l := logic.NewUserGoogleLoginLogic(r.Context(), svcCtx) + resp := l.UserGoogleLogin(&req, userinfo) + // 如果响应不为nil,则使用httpx.OkJsonCtx方法返回JSON响应; + if resp != nil { + httpx.OkJsonCtx(r.Context(), w, resp) + } else { + err := errors.New("server logic is error, resp must not be nil") + httpx.ErrorCtx(r.Context(), w, err) + logx.Error(err) + } + } +} diff --git a/server/home-user-auth/internal/handler/useroauth2loginhandler.go b/server/home-user-auth/internal/handler/useroauth2loginhandler.go new file mode 100644 index 00000000..8ad6f5f7 --- /dev/null +++ b/server/home-user-auth/internal/handler/useroauth2loginhandler.go @@ -0,0 +1,78 @@ +package handler + +import ( + "errors" + "net/http" + + "github.com/zeromicro/go-zero/core/logx" + "github.com/zeromicro/go-zero/rest/httpx" + + "fusenapi/utils/auth" + "fusenapi/utils/basic" + + "fusenapi/server/home-user-auth/internal/logic" + "fusenapi/server/home-user-auth/internal/svc" + "fusenapi/server/home-user-auth/internal/types" +) + +func UserOAuth2LoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + + var ( + // 定义错误变量 + err error + // 定义用户信息变量 + userinfo *auth.UserInfo + ) + // 解析JWT token,并对空用户进行判断 + claims, err := svcCtx.ParseJwtToken(r) + // 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &basic.Response{ + Code: 401, // 返回401状态码,表示未授权 + Message: "unauthorized", // 返回未授权信息 + }) + logx.Info("unauthorized:", err.Error()) // 记录错误日志 + return + } + + if claims != nil { + // 从token中获取对应的用户信息 + userinfo, err = auth.GetUserInfoFormMapClaims(claims) + // 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &basic.Response{ + Code: 401, + Message: "unauthorized", + }) + logx.Info("unauthorized:", err.Error()) + return + } + } else { + // 如果claims为nil,则认为用户身份为白板用户 + userinfo = &auth.UserInfo{UserId: 0, GuestId: 0} + } + + var req types.RequestOAuth + // 如果端点有请求结构体,则使用httpx.Parse方法从HTTP请求体中解析请求数据 + if err := httpx.Parse(r, &req); err != nil { + httpx.OkJsonCtx(r.Context(), w, &basic.Response{ + Code: 510, + Message: "parameter error", + }) + logx.Info(err) + return + } + // 创建一个业务逻辑层实例 + l := logic.NewUserOAuth2LoginLogic(r.Context(), svcCtx) + resp := l.UserOAuth2Login(&req, userinfo) + // 如果响应不为nil,则使用httpx.OkJsonCtx方法返回JSON响应; + if resp != nil { + httpx.OkJsonCtx(r.Context(), w, resp) + } else { + err := errors.New("server logic is error, resp must not be nil") + httpx.ErrorCtx(r.Context(), w, err) + logx.Error(err) + } + } +} diff --git a/server/home-user-auth/internal/logic/usergoogleloginlogic.go b/server/home-user-auth/internal/logic/usergoogleloginlogic.go new file mode 100644 index 00000000..ff655fe6 --- /dev/null +++ b/server/home-user-auth/internal/logic/usergoogleloginlogic.go @@ -0,0 +1,34 @@ +package logic + +import ( + "fusenapi/utils/auth" + "fusenapi/utils/basic" + + "context" + + "fusenapi/server/home-user-auth/internal/svc" + "fusenapi/server/home-user-auth/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type UserGoogleLoginLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewUserGoogleLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserGoogleLoginLogic { + return &UserGoogleLoginLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *UserGoogleLoginLogic) UserGoogleLogin(req *types.RequestGoogleLogin, userinfo *auth.UserInfo) (resp *basic.Response) { + // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) + // userinfo 传入值时, 一定不为null + + return resp.SetStatus(basic.CodeOK) +} diff --git a/server/home-user-auth/internal/logic/useroauth2loginlogic.go b/server/home-user-auth/internal/logic/useroauth2loginlogic.go new file mode 100644 index 00000000..ba11c46c --- /dev/null +++ b/server/home-user-auth/internal/logic/useroauth2loginlogic.go @@ -0,0 +1,64 @@ +package logic + +import ( + "fusenapi/utils/auth" + "fusenapi/utils/basic" + "log" + + "context" + + "fusenapi/server/home-user-auth/internal/svc" + "fusenapi/server/home-user-auth/internal/types" + + "github.com/474420502/requests" + "github.com/zeromicro/go-zero/core/logx" + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" +) + +type UserOAuth2LoginLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewUserOAuth2LoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserOAuth2LoginLogic { + + return &UserOAuth2LoginLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *UserOAuth2LoginLogic) UserOAuth2Login(req *types.RequestOAuth, userinfo *auth.UserInfo) (resp *basic.Response) { + // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) + // userinfo 传入值时, 一定不为null + switch req.Platform { + case "google": + var googleOauthConfig = &oauth2.Config{ + RedirectURL: "https://fusenh5.kayue.cn/api/user/oauth2/login/google", + ClientID: l.svcCtx.Config.OAuth[0].Appid, + ClientSecret: l.svcCtx.Config.OAuth[0].Secret, + Scopes: []string{"https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"}, + Endpoint: google.Endpoint, + } + + token, err := googleOauthConfig.Exchange(context.Background(), req.Code) + if err != nil { + resp.SetStatus(basic.CodeApiErr) + } + + resp, err := requests.Get("https://www.googleapis.com/oauth2/v2/userinfo" + token.AccessToken).Execute() + if err != nil { + panic(err) + } + log.Println(resp.Json()) + + case "facebook": + default: + + } + + return resp.SetStatus(basic.CodeOK) +} diff --git a/server/home-user-auth/internal/types/types.go b/server/home-user-auth/internal/types/types.go index c29a6734..34a18890 100644 --- a/server/home-user-auth/internal/types/types.go +++ b/server/home-user-auth/internal/types/types.go @@ -5,6 +5,24 @@ import ( "fusenapi/utils/basic" ) +type RequestGoogleLogin struct { + ID string `json:"id,,optional"` + Email string `json:"email,,optional"` + VerifiedEmail bool `json:"verified_email,,optional"` + Name string `json:"name,,optional"` + GivenName string `json:"given_name,,optional"` + FamilyName string `json:"family_name,,optional"` + Link string `json:"link,,optional"` + Picture string `json:"picture,,optional"` + Gender string `json:"gender,,optional"` + Locale string `json:"locale,,optional"` +} + +type RequestOAuth struct { + Platform string `json:"platform"` + Code string `json:"code"` +} + type RequestContactService struct { Type string `json:"type"` // 类型 RelationID int64 `json:"relation_id"` // 关系id diff --git a/server_api/home-user-auth.api b/server_api/home-user-auth.api index b5168153..a74d4b49 100644 --- a/server_api/home-user-auth.api +++ b/server_api/home-user-auth.api @@ -10,10 +10,10 @@ info ( import "basic.api" service home-user-auth { - - @handler UserRegisterHandler - post /api/user/register(RequestUserRegister) returns (response); - + + // @handler UserRegisterHandler + // post /api/user/register(RequestUserRegister) returns (response); + @handler UserLoginHandler post /api/user/login(RequestUserLogin) returns (response); @@ -49,6 +49,31 @@ service home-user-auth { @handler UserOderDeleteHandler post /api/user/order-delete(RequestOrderId) returns (response); + + @handler UserGoogleLoginHandler + post /api/user/oauth2/login/google(RequestGoogleLogin) returns (response); + + @handler UserOAuth2LoginHandler + post /api/user/oauth2/login(RequestOAuth) returns (response); + +} + +type RequestGoogleLogin { + ID string `json:"id,,optional"` + Email string `json:"email,,optional"` + VerifiedEmail bool `json:"verified_email,,optional"` + Name string `json:"name,,optional"` + GivenName string `json:"given_name,,optional"` + FamilyName string `json:"family_name,,optional"` + Link string `json:"link,,optional"` + Picture string `json:"picture,,optional"` + Gender string `json:"gender,,optional"` + Locale string `json:"locale,,optional"` +} + +type RequestOAuth { + Platform string `json:"platform"` + Code string `json:"code"` } type RequestContactService {