package middleware import ( "errors" "fmt" "strconv" "time" "go-admin/app/admin/models" "go-admin/common/middleware/handler" "go-admin/common/rediskey" "go-admin/common/statuscode" "go-admin/utils/redishelper" "github.com/bytedance/sonic" "github.com/gin-gonic/gin" "github.com/go-admin-team/go-admin-core/sdk/config" "github.com/go-admin-team/go-admin-core/sdk/pkg" jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth" ) var ErrQueryUserId = errors.New("查询用户失败") var ErrNoAccount = errors.New("没有API用户") var ErrApiUnActived = errors.New("API未激活") // AuthInit jwt验证new func AuthInit() (*jwt.GinJWTMiddleware, error) { timeout := time.Hour if config.ApplicationConfig.Mode == "dev" { timeout = time.Duration(876010) * time.Hour } else { if config.JwtConfig.Timeout != 0 { timeout = time.Duration(config.JwtConfig.Timeout) * time.Second } } return jwt.New(&jwt.GinJWTMiddleware{ Realm: "test zone", Key: []byte(config.JwtConfig.Secret), Timeout: timeout, MaxRefresh: time.Hour, PayloadFunc: handler.PayloadFunc, IdentityHandler: handler.IdentityHandler, Authenticator: handler.Authenticator, Authorizator: handler.Authorizator, Unauthorized: handler.Unauthorized, TokenLookup: "header: Authorization, query: token, cookie: jwt", TokenHeadName: "Bearer", TimeFunc: time.Now, }) } // apikey授权认证 func FrontedAuth(c *gin.Context) { // 从请求头中获取 token 和 os apikey := c.GetHeader("x-api-key") // 如果 token 不存在,返回未登录的状态 if len(apikey) == 0 { err := ResponseWithStatus(c, statuscode.Unauthorized) if err != nil { return } c.Abort() // 停止后续中间件的执行 return } // 验证 token 并获取结果 key := fmt.Sprintf(rediskey.MemberApiKey, apikey) val, err := redishelper.DefaultRedis.GetString(key) if err != nil || val == "" { ResponseWithStatus(c, statuscode.Unauthorized) c.Abort() // 停止后续中间件的执行 } // 将解析后的 token 设置到请求头中 c.Set("apiKey", apikey) // 继续处理请求 c.Next() } // ResponseWithStatus 带状态的响应 func ResponseWithStatus(ctx *gin.Context, code int, data ...interface{}) error { resp := statuscode.Response{ Code: code, Msg: "un authorized", } // resp.RequestID = pkg.GenerateMsgIDFromContext(ctx) if len(data) > 0 { resp.Data = data[0] } switch code { case 401, 500, 405, 404: ctx.JSON(code, resp) default: ctx.JSON(200, resp) } return nil } // 获取ApiKey用户id func GetUserIdWithApiKey(ctx *gin.Context) (int, error) { apikey, ok := ctx.Get("apiKey") if !ok { return 0, errors.New("apiKey not found") } return strconv.Atoi(apikey.(string)) } // 获取用户id 根据ApiKey func GetUserIdByApiKey(c *gin.Context) (int, error) { apiKey, ok := c.Get("apiKey") if !ok { return 0, errors.New("apiKey not found") } db, err := pkg.GetOrm(c) if err != nil { return 0, err } var userId int val, err := redishelper.DefaultRedis.GetString(fmt.Sprintf(rediskey.MemberApiKey, apiKey)) if err != nil { return userId, err } if val == "" { var user models.MemberApi if dbErr := db.Model(&user).Where("api_key = ?", apiKey).First(&user).Error; dbErr != nil { return userId, ErrNoAccount } if user.Status != 1 { return userId, ErrApiUnActived } userId = user.UserId } else { data := models.MemberApi{} err = sonic.UnmarshalString(val, &data) if err != nil { return userId, err } userId = data.UserId } return userId, nil }