From 427140f14091ff935d5e65f70bd2333879c529d5 Mon Sep 17 00:00:00 2001 From: eson <9673575+githubcontent@user.noreply.gitee.com> Date: Mon, 12 Jun 2023 15:17:42 +0800 Subject: [PATCH] =?UTF-8?q?jwt=20=E8=AE=A4=E8=AF=81=E5=88=9D=E6=AD=A5?= =?UTF-8?q?=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/launch.json | 16 ++++++++ go.mod | 8 +++- go.sum | 19 ++++++---- goctl_template/api/context.tpl | 28 ++++++++++++++ goctl_template/api/handler.tpl | 31 +++++++++++++++- goctl_template/api/logic.tpl | 6 ++- goctl_template/api/types.tpl | 1 - server/home-user-auth/home-user-auth.go | 16 ++++++++ server/home-user-auth/home-user-auth_test.go | 30 ++++++++++++--- .../home-user-auth/internal/handler/routes.go | 6 --- .../handler/useraddresslisthandler.go | 22 ++++++++++- .../internal/handler/userbasicinfohandler.go | 31 +++++++++++++++- .../internal/handler/userbasicinfohandler.go1 | 37 +++++++++++++++++++ .../internal/handler/userfontshandler.go | 31 +++++++++++++++- .../internal/handler/userfontshandler.go1 | 37 +++++++++++++++++++ .../internal/handler/usergettypehandler.go | 31 +++++++++++++++- .../internal/handler/usergettypehandler.go1 | 37 +++++++++++++++++++ .../internal/handler/userloginhandler.go | 8 +++- .../handler/usersavebasicinfohandler.go | 31 +++++++++++++++- .../handler/usersavebasicinfohandler.go1 | 37 +++++++++++++++++++ .../handler/userstatusconfighandler.go | 31 +++++++++++++++- .../handler/userstatusconfighandler.go1 | 37 +++++++++++++++++++ .../internal/logic/useraddresslistlogic.go | 14 ++++--- .../logic/useraddresslistlogic_test.go | 36 ++++++++++-------- .../internal/logic/userbasicinfologic.go | 2 +- .../internal/logic/userfontslogic.go | 3 +- .../internal/logic/usergettypelogic.go | 4 +- .../internal/logic/userloginlogic.go | 28 +++++++------- .../internal/logic/usersavebasicinfologic.go | 2 +- .../internal/logic/userstatusconfiglogic.go | 3 +- .../internal/svc/servicecontext.go | 33 ++++++++++++++++- server_api/home-user-auth.api | 7 +--- utils/auth/user.go | 32 ++++++++++++++++ 33 files changed, 610 insertions(+), 85 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 server/home-user-auth/internal/handler/userbasicinfohandler.go1 create mode 100644 server/home-user-auth/internal/handler/userfontshandler.go1 create mode 100644 server/home-user-auth/internal/handler/usergettypehandler.go1 create mode 100644 server/home-user-auth/internal/handler/usersavebasicinfohandler.go1 create mode 100644 server/home-user-auth/internal/handler/userstatusconfighandler.go1 diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..d742b2b3 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Package", + "type": "go", + "request": "launch", + "mode": "test", + "program": "${workspaceFolder}/server/home-user-auth", + "args": ["-test.run", "^TestMain$"] + } + ] +} \ No newline at end of file diff --git a/go.mod b/go.mod index b54b45c3..2009f271 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,12 @@ require ( golang.org/x/image v0.0.0-20190802002840-cff245a6509b ) -require github.com/474420502/requests v1.22.0 // indirect +require ( + github.com/474420502/requests v1.30.0 + github.com/tidwall/gjson v1.12.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect +) require ( github.com/beorn7/perks v1.0.1 // indirect @@ -24,7 +29,6 @@ require ( github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/go-sql-driver/mysql v1.7.0 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect - github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.3 // indirect github.com/google/pprof v0.0.0-20211214055906-6f57359322fd // indirect github.com/google/uuid v1.3.0 // indirect diff --git a/go.sum b/go.sum index a14fea8b..dd7e02fa 100644 --- a/go.sum +++ b/go.sum @@ -31,8 +31,9 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/474420502/requests v1.22.0 h1:dRQczuYg3K3GlaQgm8SZQLmpiKc+jlOKzN0LkAKXUAo= -github.com/474420502/requests v1.22.0/go.mod h1:043PKfW//QR069XTYG5WT7t+z+d+8/C5PJtfWzpsf+o= +github.com/474420502/random v0.4.1 h1:HUUyLXRWMijVb7CJoEC16f0aFQOW25Lkr80Mut6PoKU= +github.com/474420502/requests v1.30.0 h1:IVEee0wALTweoXrFsEipQEMakcSQpE5NahyMVUliMNc= +github.com/474420502/requests v1.30.0/go.mod h1:043PKfW//QR069XTYG5WT7t+z+d+8/C5PJtfWzpsf+o= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= @@ -65,6 +66,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/elazarl/goproxy v0.0.0-20210801061803-8e322dfb79c4 h1:lS3P5Nw3oPO05Lk2gFiYUOL3QPaH+fRoI1wFOc4G1UY= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -107,8 +109,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -168,6 +168,7 @@ github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1: github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -220,10 +221,15 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/tidwall/gjson v1.12.0 h1:61wEp/qfvFnqKH/WCI3M8HuRut+mHT6Mr82QrFmM2SY= +github.com/tidwall/gjson v1.12.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/gopher-lua v1.1.0 h1:BojcDhfyDWgU2f2TOzYK/g5p2gxMrku8oupLDqlnSqE= github.com/zeromicro/go-zero v1.5.2 h1:vpMlZacCMtgdtYzKI3OMyhS6mZ9UQctiAh0J7gIq31I= github.com/zeromicro/go-zero v1.5.2/go.mod h1:ndCd1nMMAdEMZgPfdm1fpavHUdBW0ykB6ckCRaSG10w= @@ -292,7 +298,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -336,7 +341,6 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -421,7 +425,6 @@ golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/goctl_template/api/context.tpl b/goctl_template/api/context.tpl index 99773904..d4a06b2b 100644 --- a/goctl_template/api/context.tpl +++ b/goctl_template/api/context.tpl @@ -12,9 +12,37 @@ type ServiceContext struct { } func NewServiceContext(c {{.config}}) *ServiceContext { + return &ServiceContext{ Config: c, MysqlConn: sqlx.NewMysql(c.SourceMysql), {{.middlewareAssignment}} } } + + +func (svcCxt *ServiceContext) ParseJwtToken(r *http.Request) (jwt.MapClaims, error) { + AuthKey := r.Header.Get("Authorization") + if len(AuthKey) <= 50 { + return nil, errors.New(fmt.Sprint("Error parsing token, len:", len(AuthKey))) + } + + token, err := jwt.Parse(AuthKey, func(token *jwt.Token) (interface{}, error) { + // 检查签名方法是否为 HS256 + if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { + return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) + } + // 返回用于验证签名的密钥 + return svcCxt.Config.Auth.AccessSecret, nil + }) + if err != nil { + return nil, errors.New(fmt.Sprint("Error parsing token:", err)) + } + + // 验证成功返回 + if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { + return claims, nil + } + + return nil, errors.New(fmt.Sprint("Invalid token", err)) +} \ No newline at end of file diff --git a/goctl_template/api/handler.tpl b/goctl_template/api/handler.tpl index 336b8eac..55383ba9 100644 --- a/goctl_template/api/handler.tpl +++ b/goctl_template/api/handler.tpl @@ -7,12 +7,37 @@ import ( "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/rest/httpx" + "fusenapi/utils/auth" + {{.ImportPackages}} ) func {{.HandlerName}}(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + // 解析jwtToken + claims, err := svcCtx.ParseJwtToken(r) + // 如果解析出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &types.Response{ + Code: 401, + Message: "unauthorized", + }) + logx.Info("unauthorized:", err.Error()) + } + + // 从Token里获取对应的信息 + userinfo, err := auth.GetUserInfoFormMapClaims(claims) + // 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &types.Response{ + Code: 401, + Message: "unauthorized", + }) + logx.Info("unauthorized:", err.Error()) + } + {{if .HasRequest}}var req types.{{.RequestType}} + // 如果端点有请求结构体,则使用httpx.Parse方法从HTTP请求体中解析请求数据 if err := httpx.Parse(r, &req); err != nil { httpx.OkJsonCtx(r.Context(), w, &types.Response{ Code: 510, @@ -21,9 +46,11 @@ func {{.HandlerName}}(svcCtx *svc.ServiceContext) http.HandlerFunc { logx.Info(err) return } - + // 创建一个业务逻辑层实例 {{end}}l := {{.LogicName}}.New{{.LogicType}}(r.Context(), svcCtx) - {{if .HasResp}}resp{{end}} := l.{{.Call}}({{if .HasRequest}}&req{{end}}) + {{if .HasResp}}resp{{end}} := l.{{.Call}}({{if .HasRequest}}&req, userinfo{{end}}) + // 如果响应不为nil,则使用httpx.OkJsonCtx方法返回JSON响应; + // 否则,发送500内部服务器错误的JSON响应并记录错误消息logx.Error。 if resp != nil { {{if .HasResp}}httpx.OkJsonCtx(r.Context(), w, resp){{else}}httpx.Ok(w){{end}} } else { diff --git a/goctl_template/api/logic.tpl b/goctl_template/api/logic.tpl index 163c667a..57cadfdf 100644 --- a/goctl_template/api/logic.tpl +++ b/goctl_template/api/logic.tpl @@ -1,6 +1,9 @@ package {{.pkgName}} import ( + "fusenapi/utils/auth" + "fusenapi/utils/basic" + {{.imports}} ) @@ -18,8 +21,9 @@ func New{{.logic}}(ctx context.Context, svcCtx *svc.ServiceContext) *{{.logic}} } } -func (l *{{.logic}}) {{.function}}({{.request}}) (resp *types.Response) { +func (l *{{.logic}}) {{.function}}({{.request}}, userinfo *auth.UserInfo) (resp *types.Response) { // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) + // userinfo 传入值时, 一定不为null {{.returnString}} resp.SetStatus(basic.CodeOK) } diff --git a/goctl_template/api/types.tpl b/goctl_template/api/types.tpl index bfa37ba0..b1734d42 100644 --- a/goctl_template/api/types.tpl +++ b/goctl_template/api/types.tpl @@ -8,7 +8,6 @@ import ( {{.types}} - // Set 设置Response的Code和Message值 func (resp *Response) Set(Code int, Message string) *Response { return &Response{ diff --git a/server/home-user-auth/home-user-auth.go b/server/home-user-auth/home-user-auth.go index 7e44ddff..502ccb9b 100644 --- a/server/home-user-auth/home-user-auth.go +++ b/server/home-user-auth/home-user-auth.go @@ -29,3 +29,19 @@ func main() { fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port) server.Start() } + +func GetTestServer() *rest.Server { + flag.Parse() + + var c config.Config + conf.MustLoad(*configFile, &c) + + server := rest.MustNewServer(c.RestConf) + defer server.Stop() + + ctx := svc.NewServiceContext(c) + handler.RegisterHandlers(server, ctx) + + fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port) + return server +} diff --git a/server/home-user-auth/home-user-auth_test.go b/server/home-user-auth/home-user-auth_test.go index 8bf4353a..885264f5 100644 --- a/server/home-user-auth/home-user-auth_test.go +++ b/server/home-user-auth/home-user-auth_test.go @@ -1,15 +1,33 @@ package main import ( + "flag" + "fmt" + "fusenapi/server/home-user-auth/internal/config" + "fusenapi/server/home-user-auth/internal/handler" + "fusenapi/server/home-user-auth/internal/svc" "testing" + + "github.com/zeromicro/go-zero/core/conf" + "github.com/zeromicro/go-zero/rest" ) -type FsCanteenType struct { - Id int64 `db:"id"` // ID - Name string `db:"name"` // 餐厅名字 - Sort int64 `db:"sort"` // 排序 - Status int64 `db:"status"` // 状态位 1启用0停用 - Ctime int64 `db:"ctime"` // 添加时间 +// var configFile = flag.String("f", "etc/home-user-auth.yaml", "the config file") + +func GetTestServer() *rest.Server { + flag.Parse() + + var c config.Config + conf.MustLoad(*configFile, &c) + + server := rest.MustNewServer(c.RestConf) + defer server.Stop() + + ctx := svc.NewServiceContext(c) + handler.RegisterHandlers(server, ctx) + + fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port) + return server } func TestMain(t *testing.T) { diff --git a/server/home-user-auth/internal/handler/routes.go b/server/home-user-auth/internal/handler/routes.go index a1e38fcf..5738d5a4 100644 --- a/server/home-user-auth/internal/handler/routes.go +++ b/server/home-user-auth/internal/handler/routes.go @@ -37,11 +37,6 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/user/status-config", Handler: UserStatusConfigHandler(serverCtx), }, - }, - ) - - server.AddRoutes( - []rest.Route{ { Method: http.MethodGet, Path: "/user/basic-info", @@ -53,6 +48,5 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Handler: UserAddressListHandler(serverCtx), }, }, - rest.WithJwt(serverCtx.Config.Auth.AccessSecret), ) } diff --git a/server/home-user-auth/internal/handler/useraddresslisthandler.go b/server/home-user-auth/internal/handler/useraddresslisthandler.go index c34909ba..b1f59a6f 100644 --- a/server/home-user-auth/internal/handler/useraddresslisthandler.go +++ b/server/home-user-auth/internal/handler/useraddresslisthandler.go @@ -10,10 +10,30 @@ import ( "fusenapi/server/home-user-auth/internal/logic" "fusenapi/server/home-user-auth/internal/svc" "fusenapi/server/home-user-auth/internal/types" + "fusenapi/utils/auth" ) func UserAddressListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + + claims, err := svcCtx.ParseJwtToken(r) + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &types.Response{ + Code: 401, + Message: "unauthorized", + }) + logx.Info("unauthorized:", err.Error()) + } + + userinfo, err := auth.GetUserInfoFormMapClaims(claims) + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &types.Response{ + Code: 401, + Message: "unauthorized", + }) + logx.Info("unauthorized:", err.Error()) + } + var req types.Request if err := httpx.Parse(r, &req); err != nil { httpx.OkJsonCtx(r.Context(), w, &types.Response{ @@ -25,7 +45,7 @@ func UserAddressListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { } l := logic.NewUserAddressListLogic(r.Context(), svcCtx) - resp := l.UserAddressList(&req) + resp := l.UserAddressList(&req, userinfo) if resp != nil { httpx.OkJsonCtx(r.Context(), w, resp) } else { diff --git a/server/home-user-auth/internal/handler/userbasicinfohandler.go b/server/home-user-auth/internal/handler/userbasicinfohandler.go index f943a476..dfbe5d59 100644 --- a/server/home-user-auth/internal/handler/userbasicinfohandler.go +++ b/server/home-user-auth/internal/handler/userbasicinfohandler.go @@ -7,6 +7,8 @@ import ( "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/rest/httpx" + "fusenapi/utils/auth" + "fusenapi/server/home-user-auth/internal/logic" "fusenapi/server/home-user-auth/internal/svc" "fusenapi/server/home-user-auth/internal/types" @@ -14,7 +16,30 @@ import ( func UserBasicInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + // 解析jwtToken + claims, err := svcCtx.ParseJwtToken(r) + // 如果解析出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &types.Response{ + Code: 401, + Message: "unauthorized", + }) + logx.Info("unauthorized:", err.Error()) + } + + // 从Token里获取对应的信息 + userinfo, err := auth.GetUserInfoFormMapClaims(claims) + // 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &types.Response{ + Code: 401, + Message: "unauthorized", + }) + logx.Info("unauthorized:", err.Error()) + } + var req types.Request + // 如果端点有请求结构体,则使用httpx.Parse方法从HTTP请求体中解析请求数据 if err := httpx.Parse(r, &req); err != nil { httpx.OkJsonCtx(r.Context(), w, &types.Response{ Code: 510, @@ -23,9 +48,11 @@ func UserBasicInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { logx.Info(err) return } - + // 创建一个业务逻辑层实例 l := logic.NewUserBasicInfoLogic(r.Context(), svcCtx) - resp := l.UserBasicInfo(&req) + resp := l.UserBasicInfo(&req, userinfo) + // 如果响应不为nil,则使用httpx.OkJsonCtx方法返回JSON响应; + // 否则,发送500内部服务器错误的JSON响应并记录错误消息logx.Error。 if resp != nil { httpx.OkJsonCtx(r.Context(), w, resp) } else { diff --git a/server/home-user-auth/internal/handler/userbasicinfohandler.go1 b/server/home-user-auth/internal/handler/userbasicinfohandler.go1 new file mode 100644 index 00000000..f943a476 --- /dev/null +++ b/server/home-user-auth/internal/handler/userbasicinfohandler.go1 @@ -0,0 +1,37 @@ +package handler + +import ( + "errors" + "net/http" + + "github.com/zeromicro/go-zero/core/logx" + "github.com/zeromicro/go-zero/rest/httpx" + + "fusenapi/server/home-user-auth/internal/logic" + "fusenapi/server/home-user-auth/internal/svc" + "fusenapi/server/home-user-auth/internal/types" +) + +func UserBasicInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.Request + if err := httpx.Parse(r, &req); err != nil { + httpx.OkJsonCtx(r.Context(), w, &types.Response{ + Code: 510, + Message: "parameter error", + }) + logx.Info(err) + return + } + + l := logic.NewUserBasicInfoLogic(r.Context(), svcCtx) + resp := l.UserBasicInfo(&req) + 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/userfontshandler.go b/server/home-user-auth/internal/handler/userfontshandler.go index ce8effe7..512882a8 100644 --- a/server/home-user-auth/internal/handler/userfontshandler.go +++ b/server/home-user-auth/internal/handler/userfontshandler.go @@ -7,6 +7,8 @@ import ( "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/rest/httpx" + "fusenapi/utils/auth" + "fusenapi/server/home-user-auth/internal/logic" "fusenapi/server/home-user-auth/internal/svc" "fusenapi/server/home-user-auth/internal/types" @@ -14,7 +16,30 @@ import ( func UserFontsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + // 解析jwtToken + claims, err := svcCtx.ParseJwtToken(r) + // 如果解析出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &types.Response{ + Code: 401, + Message: "unauthorized", + }) + logx.Info("unauthorized:", err.Error()) + } + + // 从Token里获取对应的信息 + userinfo, err := auth.GetUserInfoFormMapClaims(claims) + // 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &types.Response{ + Code: 401, + Message: "unauthorized", + }) + logx.Info("unauthorized:", err.Error()) + } + var req types.Request + // 如果端点有请求结构体,则使用httpx.Parse方法从HTTP请求体中解析请求数据 if err := httpx.Parse(r, &req); err != nil { httpx.OkJsonCtx(r.Context(), w, &types.Response{ Code: 510, @@ -23,9 +48,11 @@ func UserFontsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { logx.Info(err) return } - + // 创建一个业务逻辑层实例 l := logic.NewUserFontsLogic(r.Context(), svcCtx) - resp := l.UserFonts(&req) + resp := l.UserFonts(&req, userinfo) + // 如果响应不为nil,则使用httpx.OkJsonCtx方法返回JSON响应; + // 否则,发送500内部服务器错误的JSON响应并记录错误消息logx.Error。 if resp != nil { httpx.OkJsonCtx(r.Context(), w, resp) } else { diff --git a/server/home-user-auth/internal/handler/userfontshandler.go1 b/server/home-user-auth/internal/handler/userfontshandler.go1 new file mode 100644 index 00000000..ce8effe7 --- /dev/null +++ b/server/home-user-auth/internal/handler/userfontshandler.go1 @@ -0,0 +1,37 @@ +package handler + +import ( + "errors" + "net/http" + + "github.com/zeromicro/go-zero/core/logx" + "github.com/zeromicro/go-zero/rest/httpx" + + "fusenapi/server/home-user-auth/internal/logic" + "fusenapi/server/home-user-auth/internal/svc" + "fusenapi/server/home-user-auth/internal/types" +) + +func UserFontsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.Request + if err := httpx.Parse(r, &req); err != nil { + httpx.OkJsonCtx(r.Context(), w, &types.Response{ + Code: 510, + Message: "parameter error", + }) + logx.Info(err) + return + } + + l := logic.NewUserFontsLogic(r.Context(), svcCtx) + resp := l.UserFonts(&req) + 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/usergettypehandler.go b/server/home-user-auth/internal/handler/usergettypehandler.go index cd759425..45651404 100644 --- a/server/home-user-auth/internal/handler/usergettypehandler.go +++ b/server/home-user-auth/internal/handler/usergettypehandler.go @@ -7,6 +7,8 @@ import ( "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/rest/httpx" + "fusenapi/utils/auth" + "fusenapi/server/home-user-auth/internal/logic" "fusenapi/server/home-user-auth/internal/svc" "fusenapi/server/home-user-auth/internal/types" @@ -14,7 +16,30 @@ import ( func UserGetTypeHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + // 解析jwtToken + claims, err := svcCtx.ParseJwtToken(r) + // 如果解析出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &types.Response{ + Code: 401, + Message: "unauthorized", + }) + logx.Info("unauthorized:", err.Error()) + } + + // 从Token里获取对应的信息 + userinfo, err := auth.GetUserInfoFormMapClaims(claims) + // 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &types.Response{ + Code: 401, + Message: "unauthorized", + }) + logx.Info("unauthorized:", err.Error()) + } + var req types.Request + // 如果端点有请求结构体,则使用httpx.Parse方法从HTTP请求体中解析请求数据 if err := httpx.Parse(r, &req); err != nil { httpx.OkJsonCtx(r.Context(), w, &types.Response{ Code: 510, @@ -23,9 +48,11 @@ func UserGetTypeHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { logx.Info(err) return } - + // 创建一个业务逻辑层实例 l := logic.NewUserGetTypeLogic(r.Context(), svcCtx) - resp := l.UserGetType(&req) + resp := l.UserGetType(&req, userinfo) + // 如果响应不为nil,则使用httpx.OkJsonCtx方法返回JSON响应; + // 否则,发送500内部服务器错误的JSON响应并记录错误消息logx.Error。 if resp != nil { httpx.OkJsonCtx(r.Context(), w, resp) } else { diff --git a/server/home-user-auth/internal/handler/usergettypehandler.go1 b/server/home-user-auth/internal/handler/usergettypehandler.go1 new file mode 100644 index 00000000..cd759425 --- /dev/null +++ b/server/home-user-auth/internal/handler/usergettypehandler.go1 @@ -0,0 +1,37 @@ +package handler + +import ( + "errors" + "net/http" + + "github.com/zeromicro/go-zero/core/logx" + "github.com/zeromicro/go-zero/rest/httpx" + + "fusenapi/server/home-user-auth/internal/logic" + "fusenapi/server/home-user-auth/internal/svc" + "fusenapi/server/home-user-auth/internal/types" +) + +func UserGetTypeHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.Request + if err := httpx.Parse(r, &req); err != nil { + httpx.OkJsonCtx(r.Context(), w, &types.Response{ + Code: 510, + Message: "parameter error", + }) + logx.Info(err) + return + } + + l := logic.NewUserGetTypeLogic(r.Context(), svcCtx) + resp := l.UserGetType(&req) + 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/userloginhandler.go b/server/home-user-auth/internal/handler/userloginhandler.go index a7dde4ef..3b926823 100644 --- a/server/home-user-auth/internal/handler/userloginhandler.go +++ b/server/home-user-auth/internal/handler/userloginhandler.go @@ -14,9 +14,12 @@ import ( "fusenapi/utils/basic" ) +// UserLoginHandler 特殊的登录获取jwt token处理 func UserLoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + var req types.RequestUserLogin + // 如果端点有请求结构体,则使用httpx.Parse方法从HTTP请求体中解析请求数据 if err := httpx.Parse(r, &req); err != nil { httpx.OkJsonCtx(r.Context(), w, &types.Response{ Code: 510, @@ -25,12 +28,15 @@ func UserLoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { logx.Info(err) return } - + // 创建一个业务逻辑层实例 l := logic.NewUserLoginLogic(r.Context(), svcCtx) resp, token := l.UserLogin(&req) if resp.Code == basic.CodeOK.Code { w.Header().Add("Authorization", fmt.Sprintf("Bearer %s", token)) } + + // 如果响应不为nil,则使用httpx.OkJsonCtx方法返回JSON响应; + // 否则,发送500内部服务器错误的JSON响应并记录错误消息logx.Error。 if resp != nil { httpx.OkJsonCtx(r.Context(), w, resp) } else { diff --git a/server/home-user-auth/internal/handler/usersavebasicinfohandler.go b/server/home-user-auth/internal/handler/usersavebasicinfohandler.go index c63ff004..2969db28 100644 --- a/server/home-user-auth/internal/handler/usersavebasicinfohandler.go +++ b/server/home-user-auth/internal/handler/usersavebasicinfohandler.go @@ -7,6 +7,8 @@ import ( "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/rest/httpx" + "fusenapi/utils/auth" + "fusenapi/server/home-user-auth/internal/logic" "fusenapi/server/home-user-auth/internal/svc" "fusenapi/server/home-user-auth/internal/types" @@ -14,7 +16,30 @@ import ( func UserSaveBasicInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + // 解析jwtToken + claims, err := svcCtx.ParseJwtToken(r) + // 如果解析出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &types.Response{ + Code: 401, + Message: "unauthorized", + }) + logx.Info("unauthorized:", err.Error()) + } + + // 从Token里获取对应的信息 + userinfo, err := auth.GetUserInfoFormMapClaims(claims) + // 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &types.Response{ + Code: 401, + Message: "unauthorized", + }) + logx.Info("unauthorized:", err.Error()) + } + var req types.RequestBasicInfoForm + // 如果端点有请求结构体,则使用httpx.Parse方法从HTTP请求体中解析请求数据 if err := httpx.Parse(r, &req); err != nil { httpx.OkJsonCtx(r.Context(), w, &types.Response{ Code: 510, @@ -23,9 +48,11 @@ func UserSaveBasicInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { logx.Info(err) return } - + // 创建一个业务逻辑层实例 l := logic.NewUserSaveBasicInfoLogic(r.Context(), svcCtx) - resp := l.UserSaveBasicInfo(&req) + resp := l.UserSaveBasicInfo(&req, userinfo) + // 如果响应不为nil,则使用httpx.OkJsonCtx方法返回JSON响应; + // 否则,发送500内部服务器错误的JSON响应并记录错误消息logx.Error。 if resp != nil { httpx.OkJsonCtx(r.Context(), w, resp) } else { diff --git a/server/home-user-auth/internal/handler/usersavebasicinfohandler.go1 b/server/home-user-auth/internal/handler/usersavebasicinfohandler.go1 new file mode 100644 index 00000000..c63ff004 --- /dev/null +++ b/server/home-user-auth/internal/handler/usersavebasicinfohandler.go1 @@ -0,0 +1,37 @@ +package handler + +import ( + "errors" + "net/http" + + "github.com/zeromicro/go-zero/core/logx" + "github.com/zeromicro/go-zero/rest/httpx" + + "fusenapi/server/home-user-auth/internal/logic" + "fusenapi/server/home-user-auth/internal/svc" + "fusenapi/server/home-user-auth/internal/types" +) + +func UserSaveBasicInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.RequestBasicInfoForm + if err := httpx.Parse(r, &req); err != nil { + httpx.OkJsonCtx(r.Context(), w, &types.Response{ + Code: 510, + Message: "parameter error", + }) + logx.Info(err) + return + } + + l := logic.NewUserSaveBasicInfoLogic(r.Context(), svcCtx) + resp := l.UserSaveBasicInfo(&req) + 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/userstatusconfighandler.go b/server/home-user-auth/internal/handler/userstatusconfighandler.go index e29ae441..3af61458 100644 --- a/server/home-user-auth/internal/handler/userstatusconfighandler.go +++ b/server/home-user-auth/internal/handler/userstatusconfighandler.go @@ -7,6 +7,8 @@ import ( "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/rest/httpx" + "fusenapi/utils/auth" + "fusenapi/server/home-user-auth/internal/logic" "fusenapi/server/home-user-auth/internal/svc" "fusenapi/server/home-user-auth/internal/types" @@ -14,7 +16,30 @@ import ( func UserStatusConfigHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + // 解析jwtToken + claims, err := svcCtx.ParseJwtToken(r) + // 如果解析出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &types.Response{ + Code: 401, + Message: "unauthorized", + }) + logx.Info("unauthorized:", err.Error()) + } + + // 从Token里获取对应的信息 + userinfo, err := auth.GetUserInfoFormMapClaims(claims) + // 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &types.Response{ + Code: 401, + Message: "unauthorized", + }) + logx.Info("unauthorized:", err.Error()) + } + var req types.Request + // 如果端点有请求结构体,则使用httpx.Parse方法从HTTP请求体中解析请求数据 if err := httpx.Parse(r, &req); err != nil { httpx.OkJsonCtx(r.Context(), w, &types.Response{ Code: 510, @@ -23,9 +48,11 @@ func UserStatusConfigHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { logx.Info(err) return } - + // 创建一个业务逻辑层实例 l := logic.NewUserStatusConfigLogic(r.Context(), svcCtx) - resp := l.UserStatusConfig(&req) + resp := l.UserStatusConfig(&req, userinfo) + // 如果响应不为nil,则使用httpx.OkJsonCtx方法返回JSON响应; + // 否则,发送500内部服务器错误的JSON响应并记录错误消息logx.Error。 if resp != nil { httpx.OkJsonCtx(r.Context(), w, resp) } else { diff --git a/server/home-user-auth/internal/handler/userstatusconfighandler.go1 b/server/home-user-auth/internal/handler/userstatusconfighandler.go1 new file mode 100644 index 00000000..e29ae441 --- /dev/null +++ b/server/home-user-auth/internal/handler/userstatusconfighandler.go1 @@ -0,0 +1,37 @@ +package handler + +import ( + "errors" + "net/http" + + "github.com/zeromicro/go-zero/core/logx" + "github.com/zeromicro/go-zero/rest/httpx" + + "fusenapi/server/home-user-auth/internal/logic" + "fusenapi/server/home-user-auth/internal/svc" + "fusenapi/server/home-user-auth/internal/types" +) + +func UserStatusConfigHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.Request + if err := httpx.Parse(r, &req); err != nil { + httpx.OkJsonCtx(r.Context(), w, &types.Response{ + Code: 510, + Message: "parameter error", + }) + logx.Info(err) + return + } + + l := logic.NewUserStatusConfigLogic(r.Context(), svcCtx) + resp := l.UserStatusConfig(&req) + 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/useraddresslistlogic.go b/server/home-user-auth/internal/logic/useraddresslistlogic.go index fc7c8b57..242cd022 100644 --- a/server/home-user-auth/internal/logic/useraddresslistlogic.go +++ b/server/home-user-auth/internal/logic/useraddresslistlogic.go @@ -26,15 +26,17 @@ func NewUserAddressListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *U } } -func (l *UserAddressListLogic) UserAddressList(req *types.Request) (resp *types.Response) { +func (l *UserAddressListLogic) UserAddressList(req *types.Request, userinfo *auth.UserInfo) (resp *types.Response) { // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) m := model.NewFsAddressModel(l.svcCtx.MysqlConn) - user := auth.GetUserInfoFormCtx(l.ctx) - if user.UserId == 0 { - return resp.SetStatus(basic.CodeUnAuth) - } + + // user := auth.GetUserInfoFormCtx(l.ctx) + // if user.UserId == 0 { + // return resp.SetStatus(basic.CodeUnAuth) + // } + // user.UserId = 22 // model里设置了 返回值. 和 types 里的一至可以直接返回 - data, err := m.FindDataAddressList(l.ctx, user.UserId) + data, err := m.FindDataAddressList(l.ctx, 22) if err != nil { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, err.Error()) diff --git a/server/home-user-auth/internal/logic/useraddresslistlogic_test.go b/server/home-user-auth/internal/logic/useraddresslistlogic_test.go index 8c0058ad..4c79dbbe 100644 --- a/server/home-user-auth/internal/logic/useraddresslistlogic_test.go +++ b/server/home-user-auth/internal/logic/useraddresslistlogic_test.go @@ -1,28 +1,34 @@ package logic import ( + "log" "testing" + + "github.com/474420502/requests" ) func TestCaseAddressList(t *testing.T) { // http.NewRequest("POST", "http://localhost:8888/user/login", body io.Reader) - // ses := requests.NewSession() - // tp := ses.Post("http://localhost:8888/user/login") - // resp, err := tp.SetBodyAuto(map[string]interface{}{ - // "name": "devenv@sina.cn", - // "pwd": "$2y$13$6UFDMZQMEfqFYiNLpiUCi.B3fpvGEamPAjIgzUqv/u7jT05nB3pOC", - // }, requests.TypeFormData).Execute() - // if err != nil { - // panic(err) - // } - // log.Println(string(resp.Content())) + ses := requests.NewSession() + tp := ses.Post("http://localhost:8888/user/login") + resp, err := tp.SetBodyJson(map[string]interface{}{ + "name": "devenv@sina.cn", + "pwd": "$2y$13$6UFDMZQMEfqFYiNLpiUCi.B3fpvGEamPAjIgzUqv/u7jT05nB3pOC", + }).Execute() + if err != nil { + panic(err) + } + result := resp.Json() + token := result.Get("data.token") + ses.Header.Add("Authorization", token.String()) + log.Println(string(resp.Content())) - // resp, err = ses.Get("http://localhost:8888/user/address-list").Execute() - // if err != nil { - // panic(err) - // } - // log.Println(string(resp.Content())) + resp, err = ses.Get("http://localhost:8888/user/address-list").Execute() + if err != nil { + panic(err) + } + log.Println(string(resp.Content())) } diff --git a/server/home-user-auth/internal/logic/userbasicinfologic.go b/server/home-user-auth/internal/logic/userbasicinfologic.go index b3288cb8..33286661 100644 --- a/server/home-user-auth/internal/logic/userbasicinfologic.go +++ b/server/home-user-auth/internal/logic/userbasicinfologic.go @@ -25,7 +25,7 @@ func NewUserBasicInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Use } } -func (l *UserBasicInfoLogic) UserBasicInfo(req *types.Request) (resp *types.Response) { +func (l *UserBasicInfoLogic) UserBasicInfo(req *types.Request, userinfo *auth.UserInfo) (resp *types.Response) { loginInfo := auth.GetUserInfoFormCtx(l.ctx) if loginInfo.UserId == 0 { return resp.SetStatus(basic.CodeOK, "parse login info err ") diff --git a/server/home-user-auth/internal/logic/userfontslogic.go b/server/home-user-auth/internal/logic/userfontslogic.go index 1b8b83f7..88ba81b1 100644 --- a/server/home-user-auth/internal/logic/userfontslogic.go +++ b/server/home-user-auth/internal/logic/userfontslogic.go @@ -6,6 +6,7 @@ import ( "fusenapi/model" "fusenapi/server/home-user-auth/internal/svc" "fusenapi/server/home-user-auth/internal/types" + "fusenapi/utils/auth" "fusenapi/utils/basic" "github.com/zeromicro/go-zero/core/logx" @@ -25,7 +26,7 @@ func NewUserFontsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserFon } } -func (l *UserFontsLogic) UserFonts(req *types.Request) (resp *types.Response) { +func (l *UserFontsLogic) UserFonts(req *types.Request, userinfo *auth.UserInfo) (resp *types.Response) { data, err := model.NewFsFontModel(l.svcCtx.MysqlConn).FindAllOrderSortByDesc(l.ctx) if err != nil { logx.Error(err) diff --git a/server/home-user-auth/internal/logic/usergettypelogic.go b/server/home-user-auth/internal/logic/usergettypelogic.go index 855db1fd..c1c1ef9b 100644 --- a/server/home-user-auth/internal/logic/usergettypelogic.go +++ b/server/home-user-auth/internal/logic/usergettypelogic.go @@ -6,6 +6,7 @@ import ( "fusenapi/model" "fusenapi/server/home-user-auth/internal/svc" "fusenapi/server/home-user-auth/internal/types" + "fusenapi/utils/auth" "fusenapi/utils/basic" "github.com/zeromicro/go-zero/core/logx" @@ -25,7 +26,8 @@ func NewUserGetTypeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserG } } -func (l *UserGetTypeLogic) UserGetType(req *types.Request) (resp *types.Response) { +func (l *UserGetTypeLogic) UserGetType(req *types.Request, userinfo *auth.UserInfo) (resp *types.Response) { + // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) data, err := model.NewFsCanteenTypeModel(l.svcCtx.MysqlConn).FindGetType(l.ctx) if err != nil { diff --git a/server/home-user-auth/internal/logic/userloginlogic.go b/server/home-user-auth/internal/logic/userloginlogic.go index 58c9230f..289b6f08 100644 --- a/server/home-user-auth/internal/logic/userloginlogic.go +++ b/server/home-user-auth/internal/logic/userloginlogic.go @@ -7,9 +7,9 @@ import ( "fusenapi/model" "fusenapi/server/home-user-auth/internal/svc" "fusenapi/server/home-user-auth/internal/types" + "fusenapi/utils/auth" "fusenapi/utils/basic" - "github.com/golang-jwt/jwt" "github.com/zeromicro/go-zero/core/logx" ) @@ -27,46 +27,48 @@ func NewUserLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserLog } } -func (l *UserLoginLogic) genJwtToken(accessSecret string, accessExpire, nowSec, userid int64) (string, error) { - claims := make(jwt.MapClaims) - claims["exp"] = nowSec + accessExpire - claims["iat"] = nowSec - claims["userid"] = userid - token := jwt.New(jwt.SigningMethodHS256) - token.Claims = claims - return token.SignedString([]byte(accessSecret)) -} - func (l *UserLoginLogic) UserLogin(req *types.RequestUserLogin) (resp *types.Response, jwtToken string) { + // 创建一个 FsUserModel 对象 m 并实例化之,该对象用于操作 MySQL 数据库中的用户数据表。 m := model.NewFsUserModel(l.svcCtx.MysqlConn) + + // 在用户数据表中根据登录名查找用户记录,并返回 UserModel 类型的结构体对象 userModel。 userModel, err := m.FindOneByEmail(l.ctx, req.Name) + // 如果在用户数据表中没有找到登录名匹配的用户记录,则抛出 ErrNotFound 错误并返回未认证的状态码以及错误信息。 if err == model.ErrNotFound { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeServiceErr, err.Error()), jwtToken } + // 如果在用户数据表中找到了登录名匹配的用户记录,则判断密码是否匹配。 if userModel.PasswordHash != req.Password { logx.Info("密码错误") return resp.SetStatusWithMessage(basic.CodeUnAuth, "密码错误"), jwtToken } - // jwt 生成 + // 如果密码匹配,则生成 JWT Token。 nowSec := time.Now().Unix() - jwtToken, err = l.genJwtToken(l.svcCtx.Config.Auth.AccessSecret, l.svcCtx.Config.Auth.AccessExpire, nowSec, userModel.Id) + jwtToken, err = auth.GenerateJwtToken(l.svcCtx.Config.Auth.AccessSecret, l.svcCtx.Config.Auth.AccessExpire, nowSec, int(userModel.Id)) + + // 如果生成 JWT Token 失败,则抛出错误并返回未认证的状态码。 if err != nil { logx.Error(err) return resp.SetStatus(basic.CodeUnAuth), jwtToken } + // 更新 MySQL 数据库中用户记录对应的 VerificationToken 字段值为生成的 JWT Token。 err = m.UpdateVerificationToken(l.ctx, userModel.Id, jwtToken) + + // 如果更新 VerificationToken 字段失败,则返回未认证的状态码。 if err != nil { return resp.SetStatus(basic.CodeUnAuth), jwtToken } + // 构造 DataUserLogin 类型的数据对象 data 并设置其属性值为生成的 JWT Token。 data := &types.DataUserLogin{ Token: jwtToken, } + // 返回认证成功的状态码以及数据对象 data 和 JWT Token。 return resp.SetStatus(basic.CodeOK, data), jwtToken } diff --git a/server/home-user-auth/internal/logic/usersavebasicinfologic.go b/server/home-user-auth/internal/logic/usersavebasicinfologic.go index d8295142..ca0bee41 100644 --- a/server/home-user-auth/internal/logic/usersavebasicinfologic.go +++ b/server/home-user-auth/internal/logic/usersavebasicinfologic.go @@ -26,7 +26,7 @@ func NewUserSaveBasicInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) } } -func (l *UserSaveBasicInfoLogic) UserSaveBasicInfo(req *types.RequestBasicInfoForm) (resp *types.Response) { +func (l *UserSaveBasicInfoLogic) UserSaveBasicInfo(req *types.RequestBasicInfoForm, userinfo *auth.UserInfo) (resp *types.Response) { loginInfo := auth.GetUserInfoFormCtx(l.ctx) if loginInfo.UserId == 0 { return resp.SetStatus(basic.CodeOK, "parse login info err ") diff --git a/server/home-user-auth/internal/logic/userstatusconfiglogic.go b/server/home-user-auth/internal/logic/userstatusconfiglogic.go index 432e290a..cf6e158d 100644 --- a/server/home-user-auth/internal/logic/userstatusconfiglogic.go +++ b/server/home-user-auth/internal/logic/userstatusconfiglogic.go @@ -5,6 +5,7 @@ import ( "fusenapi/server/home-user-auth/internal/svc" "fusenapi/server/home-user-auth/internal/types" + "fusenapi/utils/auth" "fusenapi/utils/basic" "github.com/zeromicro/go-zero/core/logx" @@ -24,7 +25,7 @@ func NewUserStatusConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) * } } -func (l *UserStatusConfigLogic) UserStatusConfig(req *types.Request) (resp *types.Response) { +func (l *UserStatusConfigLogic) UserStatusConfig(req *types.Request, userinfo *auth.UserInfo) (resp *types.Response) { // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) data := &types.DataStatusConfig{ diff --git a/server/home-user-auth/internal/svc/servicecontext.go b/server/home-user-auth/internal/svc/servicecontext.go index 71e4ce9b..8c26ba0b 100644 --- a/server/home-user-auth/internal/svc/servicecontext.go +++ b/server/home-user-auth/internal/svc/servicecontext.go @@ -1,14 +1,17 @@ package svc import ( + "errors" + "fmt" "fusenapi/server/home-user-auth/internal/config" + "net/http" + "github.com/golang-jwt/jwt" "github.com/zeromicro/go-zero/core/stores/sqlx" ) type ServiceContext struct { - Config config.Config - + Config config.Config MysqlConn sqlx.SqlConn } @@ -18,3 +21,29 @@ func NewServiceContext(c config.Config) *ServiceContext { MysqlConn: sqlx.NewMysql(c.SourceMysql), } } + +func (svcCxt *ServiceContext) ParseJwtToken(r *http.Request) (jwt.MapClaims, error) { + AuthKey := r.Header.Get("Authorization") + if len(AuthKey) <= 50 { + return nil, errors.New(fmt.Sprint("Error parsing token, len:", len(AuthKey))) + } + + token, err := jwt.Parse(AuthKey, func(token *jwt.Token) (interface{}, error) { + // 检查签名方法是否为 HS256 + if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { + return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) + } + // 返回用于验证签名的密钥 + return []byte(svcCxt.Config.Auth.AccessSecret), nil + }) + if err != nil { + return nil, errors.New(fmt.Sprint("Error parsing token:", err)) + } + + // 验证成功返回 + if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { + return claims, nil + } + + return nil, errors.New(fmt.Sprint("Invalid token", err)) +} diff --git a/server_api/home-user-auth.api b/server_api/home-user-auth.api index 61fae409..4c978191 100644 --- a/server_api/home-user-auth.api +++ b/server_api/home-user-auth.api @@ -30,17 +30,12 @@ service home-user-auth { @handler UserStatusConfigHandler post /user/status-config(request) returns (response); -} - -@server( - jwt: Auth -) -service home-user-auth { @handler UserBasicInfoHandler get /user/basic-info(request) returns (response); @handler UserAddressListHandler get /user/address-list(request) returns (response); + } type RequestBasicInfoForm { diff --git a/utils/auth/user.go b/utils/auth/user.go index 321fa676..3b89d3a1 100644 --- a/utils/auth/user.go +++ b/utils/auth/user.go @@ -3,6 +3,10 @@ package auth import ( "context" "encoding/json" + "errors" + "fmt" + + "github.com/golang-jwt/jwt" "github.com/zeromicro/go-zero/core/logx" ) @@ -19,3 +23,31 @@ func GetUserInfoFormCtx(ctx context.Context) UserInfo { } return UserInfo{UserId: uid} } + +// 获取登录信息 +func GetUserInfoFormMapClaims(claims jwt.MapClaims) (*UserInfo, error) { + if userid, ok := claims["userid"]; ok { + uid, ok := userid.(float64) + if !ok { + err := errors.New(fmt.Sprint("parse uid form context err:", userid)) + logx.Error("parse uid form context err:", err) + return nil, err + } + + return &UserInfo{UserId: int64(uid)}, nil + } else { + err := errors.New(`userid not in claims`) + logx.Error(`userid not in claims`) + return nil, err + } +} + +func GenerateJwtToken(accessSecret string, accessExpire, nowSec int64, userid int) (string, error) { + claims := make(jwt.MapClaims) + claims["exp"] = nowSec + accessExpire + claims["iat"] = nowSec + claims["userid"] = userid + token := jwt.New(jwt.SigningMethodHS256) + token.Claims = claims + return token.SignedString([]byte(accessSecret)) +}