package basic import ( "errors" "fmt" "log" "strconv" "fusenapi/shared" "fusenapi/utils/auth" "net/http" "reflect" "github.com/golang-jwt/jwt" "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/rest/httpx" "gorm.io/gorm" ) type IJWTParse interface { ParseJwtToken(r *http.Request) (jwt.MapClaims, error) } func BeforeLogic(w http.ResponseWriter, r *http.Request, l reflect.Value) (isNext bool) { m := l.MethodByName("BeforeLogic") if m.IsValid() { result := m.Call([]reflect.Value{reflect.ValueOf(w), reflect.ValueOf(r)}) if len(result) != 0 { return false } } return true } func AfterLogic(w http.ResponseWriter, r *http.Request, l reflect.Value, resp *Response) bool { m := l.MethodByName("AfterLogic") if m.IsValid() { m.Call([]reflect.Value{reflect.ValueOf(w), reflect.ValueOf(r), reflect.ValueOf(resp)}) return true } return false } func NormalAfterLogic(w http.ResponseWriter, r *http.Request, resp *Response) { // 如果响应不为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) } } func ParseJwtToken(r *http.Request, svcCtx any) (*auth.UserInfo, error) { var userinfo *auth.UserInfo var err error // log.Println(io.ReadAll(r.Body)) token := r.Header.Get("Authorization") userId, err := strconv.ParseInt(token, 10, 64) if err != nil { userinfo = &auth.UserInfo{ UserId: userId, } } else { var secret uint64 = 0 token, info, err := auth.ParseJwtTokenHeader[auth.UserInfo](r) //解析Token头, 和payload信息 if err != nil { logx.Error(err) return nil, err } 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 } } if secret != 0 { claims, err := auth.ParseJwtTokenUint64Secret(token, secret) // 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息 if err != nil { log.Println(token) if err != nil { return nil, fmt.Errorf("unauthorized") } return nil, err } if claims != nil { // 从token中获取对应的用户信息 userinfo, err = auth.GetUserInfoFormMapClaims(claims) // 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息 if err != nil { return nil, fmt.Errorf("unauthorized") } } } else { // 白板用户 userinfo = &auth.UserInfo{UserId: 0, GuestId: 0} } } return userinfo, nil } func RequestParse(w http.ResponseWriter, r *http.Request, svcCtx any, LogicRequest any) (*auth.UserInfo, error) { // 新的解析jwtToken userinfo, err := ParseJwtToken(r, svcCtx) if err != nil { httpx.OkJsonCtx(r.Context(), w, &Response{ Code: 510, Message: err.Error(), }) } // 如果端点有请求结构体,则使用httpx.Parse方法从HTTP请求体中解析请求数据 if err = httpx.Parse(r, LogicRequest); err != nil { httpx.OkJsonCtx(r.Context(), w, &Response{ Code: 510, Message: "parameter error", }) logx.Error(err) return nil, err } // userinfo := &auth.UserInfo{UserId: 39} return userinfo, err } func RequestParseBackend(w http.ResponseWriter, r *http.Request, svcCtx IJWTParse, LogicRequest any) (userinfo *auth.BackendUserInfo, err error) { // 解析JWT token,并对空用户进行判断 claims, err := svcCtx.ParseJwtToken(r) // 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息 if err != nil { httpx.OkJsonCtx(r.Context(), w, &Response{ Code: 401, // 返回401状态码,表示未授权 Message: "unauthorized", // 返回未授权信息 }) logx.Info("unauthorized:", err.Error()) // 记录错误日志 return } if claims != nil { // 从token中获取对应的用户信息 userinfo, err = auth.GetBackendUserInfoFormMapClaims(claims) // 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息 if err != nil { httpx.OkJsonCtx(r.Context(), w, &Response{ Code: 401, Message: "unauthorized", }) logx.Info("unauthorized:", err.Error()) return } } // var req types.RequestGoogleLogin // 如果端点有请求结构体,则使用httpx.Parse方法从HTTP请求体中解析请求数据 if err = httpx.Parse(r, LogicRequest); err != nil { httpx.OkJsonCtx(r.Context(), w, &Response{ Code: 510, Message: "parameter error", }) logx.Info(err) return } return userinfo, err }