From f91f9d3230eb34bd646a099dfef6479700336293 Mon Sep 17 00:00:00 2001 From: eson <9673575+githubcontent@user.noreply.gitee.com> Date: Fri, 25 Aug 2023 15:37:35 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20jwt=20payload=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E7=9A=84=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 5 +- go.sum | 6 +- model/gmodel/fs_guest_logic.go | 4 +- .../auth/internal/logic/acceptcookielogic.go | 2 +- .../logic/useremailconfirmationlogic.go | 56 ++++++-- .../internal/logic/usergoogleloginlogic.go | 4 +- .../auth/internal/logic/userregisterlogic.go | 2 + .../internal/logic/userresettokenlogic.go | 2 + server/auth/internal/logic/websocket_test.go | 40 ++++++ utils/auth/jwt_token.go | 53 +++++++- utils/auth/register.go | 2 + utils/auth/user.go | 2 +- utils/auth/user_test.go | 4 +- utils/basic/request_parse.go | 125 +++++++++--------- utils/basic/request_parse_test.go | 12 ++ utils/encryption_decryption/aes_crt.go | 2 +- utils/encryption_decryption/aes_gcm.go | 2 +- utils/websocket_data/event_test.go | 13 -- .../{websocket_data => wevent}/base_event.go | 20 ++- utils/{websocket_data => wevent}/event.go | 2 +- utils/wevent/event_test.go | 14 ++ 21 files changed, 263 insertions(+), 109 deletions(-) create mode 100644 server/auth/internal/logic/websocket_test.go create mode 100644 utils/basic/request_parse_test.go delete mode 100644 utils/websocket_data/event_test.go rename utils/{websocket_data => wevent}/base_event.go (76%) rename utils/{websocket_data => wevent}/event.go (85%) create mode 100644 utils/wevent/event_test.go diff --git a/go.mod b/go.mod index 2c4e7279..62244004 100644 --- a/go.mod +++ b/go.mod @@ -68,11 +68,10 @@ require ( 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 - gorm.io/datatypes v1.2.0 // indirect ) require ( - github.com/474420502/requests v1.40.0 + github.com/474420502/requests v1.42.0 github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/tidwall/gjson v1.12.0 @@ -114,7 +113,7 @@ 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.12.0 + 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 diff --git a/go.sum b/go.sum index 6471a8ae..815b0b69 100644 --- a/go.sum +++ b/go.sum @@ -38,8 +38,8 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 github.com/474420502/passer v0.0.1 h1:ZWnt7hpFzsYDV7LHSEyLvLUvW5mRxrnDmgFdIl17q3w= github.com/474420502/passer v0.0.1/go.mod h1:MmnnrF9d51sPkFzdRq2pQtxQKqyjburVM1LjMbOCezE= github.com/474420502/random v0.4.1 h1:HUUyLXRWMijVb7CJoEC16f0aFQOW25Lkr80Mut6PoKU= -github.com/474420502/requests v1.40.0 h1:VDuLxSG/3IGBvMfjPV8+o7s1l5mOwLAgfo5Og6vMAJw= -github.com/474420502/requests v1.40.0/go.mod h1:2SCVzim0ONFYG09g/GrM7RTeJIC6qTyZfnohsjnG5C8= +github.com/474420502/requests v1.42.0 h1:aUj0rWhfldbOOlGHDIcqT9zgXEoSlK4IBmRF3LxI1+Y= +github.com/474420502/requests v1.42.0/go.mod h1:2SCVzim0ONFYG09g/GrM7RTeJIC6qTyZfnohsjnG5C8= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= 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= @@ -979,8 +979,6 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/datatypes v1.2.0 h1:5YT+eokWdIxhJgWHdrb2zYUimyk0+TaFth+7a0ybzco= -gorm.io/datatypes v1.2.0/go.mod h1:o1dh0ZvjIjhH/bngTpypG6lVRJ5chTBxE09FH/71k04= gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw= gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o= gorm.io/gorm v1.25.1 h1:nsSALe5Pr+cM3V1qwwQ7rOkw+6UeLrX5O4v3llhHa64= diff --git a/model/gmodel/fs_guest_logic.go b/model/gmodel/fs_guest_logic.go index 938a5cd8..6e49a74c 100755 --- a/model/gmodel/fs_guest_logic.go +++ b/model/gmodel/fs_guest_logic.go @@ -9,14 +9,14 @@ import ( "gorm.io/gorm" ) -func (m *FsGuestModel) GenerateGuestID(ctx context.Context, AccessSecret *string) (authKey string, err error) { +func (m *FsGuestModel) GenerateGuestID(ctx context.Context, AccessSecret uint64) (authKey string, err error) { err = m.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { now := time.Now().Unix() var record = &FsGuest{} tx.Create(record) - authKey, err = auth.GenerateJwtToken(AccessSecret, now, 31536000, 0, int64(record.GuestId)) + authKey, err = auth.GenerateJwtTokenUint64(AccessSecret, now, 31536000, 0, int64(record.GuestId)) if err != nil { logx.Error(err) err = tx.Rollback().Error diff --git a/server/auth/internal/logic/acceptcookielogic.go b/server/auth/internal/logic/acceptcookielogic.go index aa57d085..963fdfd9 100644 --- a/server/auth/internal/logic/acceptcookielogic.go +++ b/server/auth/internal/logic/acceptcookielogic.go @@ -44,7 +44,7 @@ func (l *AcceptCookieLogic) AcceptCookie(req *types.Request, userinfo *auth.User } m := l.svcCtx.AllModels.FsGuest - token, err := m.GenerateGuestID(l.ctx, &l.svcCtx.Config.Auth.AccessSecret) + token, err := m.GenerateGuestID(l.ctx, auth.DefaultJwtSecret) if err != nil { return resp.SetStatus(basic.CodeGuestGenErr) } diff --git a/server/auth/internal/logic/useremailconfirmationlogic.go b/server/auth/internal/logic/useremailconfirmationlogic.go index e7487cf1..163ca27b 100644 --- a/server/auth/internal/logic/useremailconfirmationlogic.go +++ b/server/auth/internal/logic/useremailconfirmationlogic.go @@ -1,9 +1,10 @@ package logic import ( + "fmt" "fusenapi/utils/auth" "fusenapi/utils/basic" - "log" + "fusenapi/utils/wevent" "time" "context" @@ -11,6 +12,7 @@ import ( "fusenapi/server/auth/internal/svc" "fusenapi/server/auth/internal/types" + "github.com/474420502/requests" "github.com/zeromicro/go-zero/core/logx" ) @@ -53,7 +55,7 @@ func (l *UserEmailConfirmationLogic) UserEmailConfirmation(req *types.RequestEma // 谷歌平台的注册流程 user, err := l.svcCtx.AllModels.FsUser.RegisterByGoogleOAuth(l.ctx, token) if err != nil { - logx.Error(err) + logx.Error(err, token.TraceId) return resp.SetStatus(basic.CodeDbSqlErr) } @@ -67,18 +69,40 @@ func (l *UserEmailConfirmationLogic) UserEmailConfirmation(req *types.RequestEma ) if err != nil { - logx.Error(err) + logx.Error(err, token.TraceId) return } - log.Println(jwtToken) // 通过websocket去, 送回通道 + event := wevent.NewWebsocketEventSuccess(wevent.UserEmailRegister, token.TraceId) + event.Data = wevent.DataEmailRegister{ + JwtToken: jwtToken, + } + + tp := requests.Post(fmt.Sprintf("%s/api/websocket/common_notify", l.svcCtx.Config.MainAddress)) + tp.SetBodyJson(requests.M{ + "wid": token.Wid, + "data": event, + }) + + wresp, err := tp.Execute() + if err != nil { + logx.Error(err, token.TraceId) + return + } + + result := wresp.Json() + if result.Get("code").Int() != 200 { + logx.Error(result.Get("message")) + return + } + logx.Info("success", token.TraceId, jwtToken) case "facebook": case "fusen": user, err := l.svcCtx.AllModels.FsUser.RegisterByFusen(l.ctx, token) if err != nil { - logx.Error(err) + logx.Error(err, token.TraceId) return resp.SetStatus(basic.CodeDbSqlErr) } @@ -92,12 +116,28 @@ func (l *UserEmailConfirmationLogic) UserEmailConfirmation(req *types.RequestEma ) if err != nil { - logx.Error(err) + logx.Error(err, token.TraceId) return } - log.Println(jwtToken) - + event := wevent.NewWebsocketEventSuccess(wevent.UserEmailRegister, token.TraceId) + event.Data = wevent.DataEmailRegister{ + JwtToken: jwtToken, + } + tp := requests.Post(fmt.Sprintf("%s/api/websocket/common_notify", l.svcCtx.Config.MainAddress)) + tp.SetBodyJson(requests.M{ + "wid": token.Wid, + "data": event, + }) + wresp, err := tp.Execute() + if err != nil { + logx.Error(err, token.TraceId) + } + result := wresp.Json() + if result.Get("code").Int() != 200 { + logx.Error(result.Get("message")) + } + logx.Info("success", token.TraceId, jwtToken) } default: diff --git a/server/auth/internal/logic/usergoogleloginlogic.go b/server/auth/internal/logic/usergoogleloginlogic.go index d84bc20f..8da743ab 100644 --- a/server/auth/internal/logic/usergoogleloginlogic.go +++ b/server/auth/internal/logic/usergoogleloginlogic.go @@ -17,6 +17,7 @@ import ( "fusenapi/server/auth/internal/types" "github.com/474420502/requests" + "github.com/google/uuid" "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/rest/httpx" "golang.org/x/oauth2" @@ -91,9 +92,10 @@ func (l *UserGoogleLoginLogic) UserGoogleLogin(req *types.RequestGoogleLogin, us l.registerInfo = &auth.RegisterToken{ Id: googleId, - Password: base64.URLEncoding.EncodeToString(nonce), + Password: base64.RawURLEncoding.EncodeToString(nonce), Platform: "google", OperateType: auth.OpTypeRegister, + TraceId: uuid.NewString(), CreateAt: time.Now(), } diff --git a/server/auth/internal/logic/userregisterlogic.go b/server/auth/internal/logic/userregisterlogic.go index 9d61b50d..12b87530 100644 --- a/server/auth/internal/logic/userregisterlogic.go +++ b/server/auth/internal/logic/userregisterlogic.go @@ -10,6 +10,7 @@ import ( "fusenapi/server/auth/internal/svc" "fusenapi/server/auth/internal/types" + "github.com/google/uuid" "github.com/zeromicro/go-zero/core/logx" ) @@ -48,6 +49,7 @@ func (l *UserRegisterLogic) UserRegister(req *types.RequestUserRegister, userinf Email: req.Email, Password: req.Password, Platform: "fusen", + TraceId: uuid.NewString(), CreateAt: time.Now(), } diff --git a/server/auth/internal/logic/userresettokenlogic.go b/server/auth/internal/logic/userresettokenlogic.go index 680fbdf6..aeffc953 100644 --- a/server/auth/internal/logic/userresettokenlogic.go +++ b/server/auth/internal/logic/userresettokenlogic.go @@ -10,6 +10,7 @@ import ( "fusenapi/server/auth/internal/svc" "fusenapi/server/auth/internal/types" + "github.com/google/uuid" "github.com/zeromicro/go-zero/core/logx" ) @@ -51,6 +52,7 @@ func (l *UserResetTokenLogic) UserResetToken(req *types.RequestUserResetToken, u Wid: req.Wid, Email: *user.Email, OldPassword: *user.PasswordHash, + TraceId: uuid.NewString(), CreateAt: time.Now(), } diff --git a/server/auth/internal/logic/websocket_test.go b/server/auth/internal/logic/websocket_test.go new file mode 100644 index 00000000..da4fb0e0 --- /dev/null +++ b/server/auth/internal/logic/websocket_test.go @@ -0,0 +1,40 @@ +package logic + +import ( + "fmt" + "fusenapi/utils/wevent" + "log" + "testing" + + "github.com/474420502/requests" + "github.com/google/uuid" + "github.com/zeromicro/go-zero/core/logx" +) + +func TestSender(t *testing.T) { + traceId := uuid.NewString() + event := wevent.NewWebsocketEventSuccess(wevent.UserEmailRegister, traceId) + event.Data = wevent.DataEmailRegister{ + JwtToken: traceId, + } + + tp := requests.Post(fmt.Sprintf("%s/api/websocket/common_notify", "https://server.fusen.3718.cn:9900")) + tp.SetBodyJson(requests.M{ + "wid": "tGyMYX9EldtsPLZTyT6PxrRgEV615CQGEiu9Sb1XrjZ4kpTjI46sQyh7kYfVlgN9uR5Uw4KDF+S62IknmaRgSMdee1QHVtCv+VEKrMF76snR04zS1ZbWZCgX5Lv2xgHz/bZBWwJF/9u6YTy2/FetGg==", + "data": event, + }) + + wresp, err := tp.Execute() + if err != nil { + logx.Error(err, "traceId") + return + } + + result := wresp.Json() + if result.Get("code").Int() != 200 { + logx.Error(result.Get("message")) + return + } + log.Println(result) + +} diff --git a/utils/auth/jwt_token.go b/utils/auth/jwt_token.go index 0558229c..c5c99252 100644 --- a/utils/auth/jwt_token.go +++ b/utils/auth/jwt_token.go @@ -5,14 +5,17 @@ import ( "encoding/json" "errors" "fmt" + "log" "net/http" "strings" ) +var DefaultJwtSecret uint64 = 21321321321 + func ParseJwtTokenHeader[T any](r *http.Request) (string, *T, error) { //TODO: - var u T - return "", &u, nil + // var u T + // return "", &u, nil AuthKey := r.Header.Get("Authorization") if AuthKey == "" { @@ -28,7 +31,51 @@ func ParseJwtTokenHeader[T any](r *http.Request) (string, *T, error) { return "", nil, fmt.Errorf("Invalid JWT token") } - payload, err := base64.URLEncoding.DecodeString(parts[1]) + payload, err := base64.RawURLEncoding.DecodeString(parts[1]) + if err != nil { + return "", nil, fmt.Errorf("Error unmarshalling JWT DecodeString: %s", err.Error()) + } + + var p T + err = json.Unmarshal(payload, &p) + if err != nil { + return "", nil, fmt.Errorf("Error unmarshalling JWT payload: %s", err) + } + + return AuthKey, &p, nil + + // 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(svcCtx.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)) +} + +func TParseJwtTokenHeader[T any](AuthKey string) (string, *T, error) { + //TODO: + // var u T + // return "", &u, nil + + parts := strings.Split(AuthKey, ".") + if len(parts) != 3 { + return "", nil, fmt.Errorf("Invalid JWT token") + } + + payload, err := base64.RawURLEncoding.DecodeString(parts[1]) + log.Println(string(payload)) if err != nil { return "", nil, fmt.Errorf("Error unmarshalling JWT DecodeString: %s", err.Error()) } diff --git a/utils/auth/register.go b/utils/auth/register.go index bd69f8d1..9857abb4 100644 --- a/utils/auth/register.go +++ b/utils/auth/register.go @@ -20,6 +20,7 @@ type RegisterToken struct { Email string // email Password string // 密码 Platform string // 平台 + TraceId string //链路Id CreateAt time.Time // 创建时间 } @@ -29,6 +30,7 @@ type ResetToken struct { Wid string // websocket 通道id Email string // email OldPassword string // 旧密码 + TraceId string //链路Id CreateAt time.Time // 创建时间 } diff --git a/utils/auth/user.go b/utils/auth/user.go index 14b676e1..aaa7c357 100644 --- a/utils/auth/user.go +++ b/utils/auth/user.go @@ -216,7 +216,7 @@ func getJwtClaims(AuthKey string, AccessSecret *string) (jwt.MapClaims, error) { func PasswordHash(pwd string) string { h := sha256.New() h.Write([]byte(pwd)) - return base64.URLEncoding.EncodeToString(h.Sum(nil)) + return base64.RawURLEncoding.EncodeToString(h.Sum(nil)) } func CheckValueRange[T comparable](v T, rangevalues ...T) bool { diff --git a/utils/auth/user_test.go b/utils/auth/user_test.go index 35b72d91..d04bc48e 100644 --- a/utils/auth/user_test.go +++ b/utils/auth/user_test.go @@ -60,10 +60,10 @@ func TestCase1(t *testing.T) { a := sha256.New() a.Write([]byte("fusen_backend_3021")) - base64.URLEncoding.EncodeToString(a.Sum(nil)) + base64.RawURLEncoding.EncodeToString(a.Sum(nil)) as := fmt.Sprintf("%x", a.Sum(nil)) - log.Println(as, len(as), base64.URLEncoding.EncodeToString(a.Sum(nil))) + log.Println(as, len(as), base64.RawURLEncoding.EncodeToString(a.Sum(nil))) // b := sha256.New().Sum([]byte("fusen_backend_2022")) // bs := fmt.Sprintf("%x", b) diff --git a/utils/basic/request_parse.go b/utils/basic/request_parse.go index e500e8ad..4dd2787f 100644 --- a/utils/basic/request_parse.go +++ b/utils/basic/request_parse.go @@ -3,6 +3,7 @@ package basic import ( "errors" + "fusenapi/shared" "fusenapi/utils/auth" "net/http" "reflect" @@ -10,10 +11,9 @@ import ( "github.com/golang-jwt/jwt" "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/rest/httpx" + "gorm.io/gorm" ) -var DefaultJwtSecret uint64 = 21321321321 - type IJWTParse interface { ParseJwtToken(r *http.Request) (jwt.MapClaims, error) } @@ -52,67 +52,68 @@ func NormalAfterLogic(w http.ResponseWriter, r *http.Request, resp *Response) { } func RequestParse(w http.ResponseWriter, r *http.Request, svcCtx any, LogicRequest any) (*auth.UserInfo, error) { - // log.Println(io.ReadAll(r.Body)) - // token, info, err := auth.ParseJwtTokenHeader[auth.UserInfo](r) //解析Token头, 和payload信息 - // if err != nil { - // logx.Error(err) - // return nil, err - // } - - // var secret uint64 = 0 - // if info != nil { - - // if info.IsUser() { - // // us, err := state.GetUserState(info.UserId) //获取缓存的用户状态 - // reflect.ValueOf(svcCtx) - - // ctxValue := reflect.ValueOf(svcCtx).FieldByName("MysqlConn") - // gdb := ctxValue.Interface().(*gorm.DB) - - // us, err := shared.GetUserState(info.UserId, gdb) - // if err != nil { - // logx.Error(err) - // return nil, err - // } - // secret = us.PwdHash // 获取密码的hash做jwt, 便于重置密码的使用 - - // } else if info.IsGuest() { - // secret = DefaultJwtSecret //获取默认的hash - // } - // } - - // var userinfo *auth.UserInfo - // if secret != 0 { - // claims, err := auth.ParseJwtTokenUint64Secret(token, secret) - // // 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息 - // if err != nil { - // httpx.OkJsonCtx(r.Context(), w, &Response{ - // Code: 401, // 返回401状态码,表示未授权 - // Message: "unauthorized", // 返回未授权信息 - // }) - // logx.Info("unauthorized:", err.Error()) // 记录错误日志 - // return nil, err - // } - - // if claims != nil { - // // 从token中获取对应的用户信息 - // userinfo, err = auth.GetUserInfoFormMapClaims(claims) - // // 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息 - // if err != nil { - // httpx.OkJsonCtx(r.Context(), w, &Response{ - // Code: 401, - // Message: "unauthorized", - // }) - // logx.Info("unauthorized:", err.Error()) - // return nil, err - // } - // } - // } else { - // // 白板用户 - // userinfo = &auth.UserInfo{UserId: 0, GuestId: 0} - // } var err error + // log.Println(io.ReadAll(r.Body)) + token, info, err := auth.ParseJwtTokenHeader[auth.UserInfo](r) //解析Token头, 和payload信息 + + if err != nil { + logx.Error(err) + return nil, err + } + + var secret uint64 = 0 + if info != nil { + + if info.IsUser() { + // us, err := state.GetUserState(info.UserId) //获取缓存的用户状态 + reflect.ValueOf(svcCtx) + ctxValue := reflect.ValueOf(svcCtx).FieldByName("MysqlConn") + gdb := ctxValue.Interface().(*gorm.DB) + + us, err := shared.GetUserState(info.UserId, gdb) + if err != nil { + logx.Error(err) + return nil, err + } + secret = us.PwdHash // 获取密码的hash做jwt, 便于重置密码的使用 + + } else if info.IsGuest() { + secret = auth.DefaultJwtSecret //获取默认的hash + } + } + + var userinfo *auth.UserInfo + if secret != 0 { + claims, err := auth.ParseJwtTokenUint64Secret(token, secret) + // 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &Response{ + Code: 401, // 返回401状态码,表示未授权 + Message: "unauthorized", // 返回未授权信息 + }) + logx.Info("unauthorized:", err.Error()) // 记录错误日志 + return nil, err + } + + if claims != nil { + // 从token中获取对应的用户信息 + userinfo, err = auth.GetUserInfoFormMapClaims(claims) + // 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息 + if err != nil { + httpx.OkJsonCtx(r.Context(), w, &Response{ + Code: 401, + Message: "unauthorized", + }) + logx.Info("unauthorized:", err.Error()) + return nil, err + } + } + } else { + // 白板用户 + userinfo = &auth.UserInfo{UserId: 0, GuestId: 0} + } + // 如果端点有请求结构体,则使用httpx.Parse方法从HTTP请求体中解析请求数据 if err = httpx.Parse(r, LogicRequest); err != nil { httpx.OkJsonCtx(r.Context(), w, &Response{ @@ -122,7 +123,7 @@ func RequestParse(w http.ResponseWriter, r *http.Request, svcCtx any, LogicReque logx.Error(err) return nil, err } - userinfo := &auth.UserInfo{UserId: 39} + // userinfo := &auth.UserInfo{UserId: 39} return userinfo, err } diff --git a/utils/basic/request_parse_test.go b/utils/basic/request_parse_test.go new file mode 100644 index 00000000..ac8fac7a --- /dev/null +++ b/utils/basic/request_parse_test.go @@ -0,0 +1,12 @@ +package basic + +import ( + "fusenapi/utils/auth" + "log" + "testing" +) + +func TestRequestParse(t *testing.T) { + a, us, err := auth.TParseJwtTokenHeader[auth.UserInfo]("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MjQ0NzE1MzUsImd1ZXN0X2lkIjo0OCwiaWF0IjozMTUzNjAwMCwidXNlcl9pZCI6MH0.jsIpl9CeQdGHRERPByVtMlPLxaxzBaorJsmtfQqbgVc") + log.Println(a, us, err) +} diff --git a/utils/encryption_decryption/aes_crt.go b/utils/encryption_decryption/aes_crt.go index 0720ccd0..7e612d52 100644 --- a/utils/encryption_decryption/aes_crt.go +++ b/utils/encryption_decryption/aes_crt.go @@ -27,7 +27,7 @@ func NewSecretCRT[T any](key string, iv string) *SecretCRT[T] { s := &SecretCRT[T]{ derivationKey: DerivationKeyV1, iv: []byte(iv), - EncDec: base64.URLEncoding, + EncDec: base64.RawURLEncoding, } s.secretKey = s.derivationKey(key) return s diff --git a/utils/encryption_decryption/aes_gcm.go b/utils/encryption_decryption/aes_gcm.go index 25bee8b7..45e2dc00 100644 --- a/utils/encryption_decryption/aes_gcm.go +++ b/utils/encryption_decryption/aes_gcm.go @@ -49,7 +49,7 @@ func NewSecretGCM[T any](key string) *SecretGCM[T] { s := &SecretGCM[T]{ srcKey: key, derivationKey: DerivationKeyV1, - EncDec: base64.URLEncoding, + EncDec: base64.RawURLEncoding, } s.secretKey = s.derivationKey(s.srcKey) return s diff --git a/utils/websocket_data/event_test.go b/utils/websocket_data/event_test.go deleted file mode 100644 index 69530e38..00000000 --- a/utils/websocket_data/event_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package websocket_data - -import ( - "encoding/json" - "log" - "testing" -) - -func TestEvent(t *testing.T) { - - data, _ := json.Marshal(NewWebsocketEvent(UserEmailRegister).WithCode(200)) - log.Println(string(data)) -} diff --git a/utils/websocket_data/base_event.go b/utils/wevent/base_event.go similarity index 76% rename from utils/websocket_data/base_event.go rename to utils/wevent/base_event.go index 6e2834cf..5bf4e6fd 100644 --- a/utils/websocket_data/base_event.go +++ b/utils/wevent/base_event.go @@ -1,9 +1,7 @@ -package websocket_data +package wevent import ( "time" - - "github.com/google/uuid" ) // 和前端交流的事件机制 @@ -24,12 +22,22 @@ type WebsocketEvent struct { } // NewWebsocketEvent 创建一个Websocket事件 -func NewWebsocketEvent(etype EventType) *WebsocketEvent { - uid := uuid.NewString() +func NewWebsocketEvent(etype EventType, TraceId string) *WebsocketEvent { return &WebsocketEvent{ Type: etype, SenderTime: time.Now().UTC(), - TraceId: uid, + TraceId: TraceId, + } +} + +// NewWebsocketEventSuccess 创建一个Websocket事件伴随Code(200) +func NewWebsocketEventSuccess(etype EventType, TraceId string) *WebsocketEvent { + return &WebsocketEvent{ + Type: etype, + SenderTime: time.Now().UTC(), + TraceId: TraceId, + Code: 200, + Message: "success", } } diff --git a/utils/websocket_data/event.go b/utils/wevent/event.go similarity index 85% rename from utils/websocket_data/event.go rename to utils/wevent/event.go index c1b88795..201324a7 100644 --- a/utils/websocket_data/event.go +++ b/utils/wevent/event.go @@ -1,4 +1,4 @@ -package websocket_data +package wevent // 用户注册成功的事件关注的数据 type DataEmailRegister struct { diff --git a/utils/wevent/event_test.go b/utils/wevent/event_test.go new file mode 100644 index 00000000..8e8e8576 --- /dev/null +++ b/utils/wevent/event_test.go @@ -0,0 +1,14 @@ +package wevent + +import ( + "encoding/json" + "log" + "testing" + + "github.com/google/uuid" +) + +func TestEvent(t *testing.T) { + data, _ := json.Marshal(NewWebsocketEvent(UserEmailRegister, uuid.NewString()).WithCode(200)) + log.Println(string(data)) +}