package controllers import ( "encoding/json" "fmt" "strings" "sws_xcx/enums" "sws_xcx/models" "sws_xcx/service" "sws_xcx/utils" "net/http" "time" "github.com/astaxie/beego" "github.com/dgrijalva/jwt-go" "github.com/google/uuid" ) func ApiControllersRegisterRouters() { //接收MQTT消息 beego.Router("/xcx/api/device/emqmsg", &MessageApiControllor{}, "Post:PutEmqxMessage") beego.Router("/xcx/api/user/login", &LoginApiController{}, "Post:WxXcxLogin") beego.Router("/xcx/api/user/updatephonebycode", &UserApiController{}, "Post:UpdatePhoneByCode") beego.Router("/xcx/api/user/getuserinfo", &UserApiController{}, "Get:GetUserInfo") beego.Router("/xcx/api/user/savehealthprofile", &UserApiController{}, "Post:SaveHealthProfile") beego.Router("/xcx/api/user/saveuserinfo", &UserApiController{}, "Post:SaveUserInfo") beego.Router("/xcx/api/user/gethealthprofile", &UserApiController{}, "Get:GetHealthProfile") beego.Router("/xcx/api/sysdic/getillness", &SysDicApiController{}, "Get:GetIllness") beego.Router("/xcx/api/sysdic/getrenalstatus", &SysDicApiController{}, "Get:GetRenalStatus") beego.Router("/xcx/api/sysdic/getcheckitems", &SysDicApiController{}, "Get:GetCheckItems") beego.Router("/xcx/api/sysdic/getdevicetypes", &SysDicApiController{}, "Get:GetDeviceTypes") } type BaseApiController struct { beego.Controller } func (c *BaseApiController) Prepare() { } type BaseApiAuthController struct { BaseApiController CurrentUser models.XcxUser sessionKey string } func (c *BaseApiAuthController) Prepare() { c.BaseApiController.Prepare() // JWT Token通常放在请求头中,例如Authorization: Bearer authHeader := c.Ctx.Input.Header("Authorization") if authHeader == "" { c.ServeFailJsonSendAndStop(http.StatusUnauthorized, enums.ErrorCodeNotLogin, "缺少认证信息") return } tokenString := authHeader if strings.Contains(authHeader, "Bearer") { tokenString = authHeader[len("Bearer "):] } token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) } //从配置文件中获取secret secret := beego.AppConfig.String("xsrfkey") return []byte(secret), nil }) if err != nil || !token.Valid { utils.ErrorLog("Token验证失败: %v", err) c.ServeFailJsonSendAndStop(http.StatusUnauthorized, enums.ErrorCodeNotLogin, "无效的Token") return } // 假设JWT中包含了用户ID claims, ok := token.Claims.(*CustomClaims) if !ok { c.ServeFailJsonSendAndStop(http.StatusUnauthorized, enums.ErrorCodeNotLogin, "无法解析Token中的信息") return } key := claims.UserID c.sessionKey = key redisCli := service.RedisClient() defer redisCli.Close() uJson, err := redisCli.Get(fmt.Sprintf("session:%v", key)).Bytes() if err != nil { c.ServeFailJsonSendAndStop(http.StatusUnauthorized, enums.ErrorCodeNotLogin, fmt.Sprintf("redis err:%v", err)) return } user := &models.XcxUser{} err = json.Unmarshal(uJson, user) if err != nil { c.ServeFailJsonSendAndStop(http.StatusUnauthorized, enums.ErrorCodeNotLogin, fmt.Sprintf("json err:%v", err)) return } //c.Ctx.Input.SetData("user", user) c.CurrentUser = *user //c.SetSession("user", user) } type CustomClaims struct { UserID string `json:"sessionkey"` jwt.StandardClaims } // 输出数据格式化 /* success json: { "state": 1, "code": 0, "data": json, } fail json: { "state": 0, "code": int, "msg": string, } */ func (c *BaseApiController) ServeSuccessJSON(data interface{}) { c.Data["json"] = enums.MakeSuccessResponseJSON(data) c.ServeJSON() } func (c *BaseApiController) ServeFailJSONWithSGJErrorCode(code int) { c.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(code) c.ServeJSON() } func (c *BaseApiController) ServeFailJSONWithSGJError(err *enums.SGJError) { c.Data["json"] = enums.MakeFailResponseJSONWithSGJError(err) c.ServeJSON() } func (c *BaseApiController) ServeFailJsonSend(code int, msg string) { c.Data["json"] = enums.MakeFailResponseJSON(msg, code) c.ServeJSON() } func (c *BaseApiController) ServeDynamicFailJsonSend(msg string) { c.Data["json"] = enums.MakeDynamicFailResponseJSON(msg) c.ServeJSON() } func (c *BaseApiController) ServeFailJsonSendAndStop(httpStatus int, errCode int, msg string) { c.Ctx.Output.SetStatus(httpStatus) c.ServeFailJsonSend(errCode, msg) c.StopRun() } func (c *BaseApiController) login(u models.XcxUser) (string, error) { key := uuid.New().String() expire, _ := beego.AppConfig.Int("xsrfexpire") if expire == 0 { expire = 7200 } uJson, _ := json.Marshal(u) redisCli := service.RedisClient() defer redisCli.Close() redisCli.Set(fmt.Sprintf("session:%v", key), uJson, time.Second*time.Duration(expire)) // 创建一个我们自己的声明 claims := CustomClaims{ UserID: key, StandardClaims: jwt.StandardClaims{ ExpiresAt: time.Now().Add(time.Second * time.Duration(expire)).Unix(), // Token有效期(默认为7200秒) Issuer: "sws_xcx", // 签发者 }, } // 使用指定的签名方法创建签名 token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) // 使用密钥签名并获得完整的编码后的字符串形式的Token return token.SignedString([]byte(beego.AppConfig.String("xsrfkey"))) } func (c *BaseApiAuthController) updateCurrentUser(updateAction func(*models.XcxUser)) error { u := &c.CurrentUser updateAction(u) err := service.NewXcxUserService().UpdateUser(u) if err != nil { //c.ServeFailJsonSendAndStop(http.StatusOK, enums.ErrorCodeDBUpdate, "更新用户信息失败") return err } redisCli := service.RedisClient() defer redisCli.Close() uJson, _ := json.Marshal(u) expire, _ := beego.AppConfig.Int("xsrfexpire") if expire == 0 { expire = 7200 } err = redisCli.Set(fmt.Sprintf("session:%v", c.sessionKey), uJson, time.Second*time.Duration(expire)).Err() if err != nil { return err } c.CurrentUser = *u return nil }