fix:: 请求响应码用常量
This commit is contained in:
@@ -20,14 +20,14 @@ func ErrorCatch() gin.HandlerFunc {
|
||||
|
||||
// 返回错误响应给客户端
|
||||
if config.Env() == "prod" {
|
||||
c.JSON(500, resp.CodeMsg(500001, "Internal Server Errors"))
|
||||
c.JSON(500, resp.CodeMsg(resp.CODE_INTERNAL, resp.MSG_INTERNAL))
|
||||
} else {
|
||||
// 通过实现 error 接口的 Error() 方法自定义错误类型进行捕获
|
||||
switch v := err.(type) {
|
||||
case error:
|
||||
c.JSON(500, resp.CodeMsg(500001, v.Error()))
|
||||
c.JSON(500, resp.CodeMsg(resp.CODE_INTERNAL, v.Error()))
|
||||
default:
|
||||
c.JSON(500, resp.CodeMsg(500001, fmt.Sprint(err)))
|
||||
c.JSON(500, resp.CodeMsg(resp.CODE_INTERNAL, fmt.Sprint(err)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ func AuthorizeOauth2(scope []string) gin.HandlerFunc {
|
||||
// 获取请求头标识信息
|
||||
tokenStr := reqctx.Authorization(c)
|
||||
if tokenStr == "" {
|
||||
c.JSON(401, resp.CodeMsg(401003, "authorization token is empty"))
|
||||
c.JSON(401, resp.CodeMsg(resp.CODE_AUTH_NOTOKEN, "authorization token is empty"))
|
||||
c.Abort() // 停止执行后续的处理函数
|
||||
return
|
||||
}
|
||||
@@ -27,7 +27,7 @@ func AuthorizeOauth2(scope []string) gin.HandlerFunc {
|
||||
// 验证令牌
|
||||
claims, err := token.Oauth2TokenVerify(tokenStr, "access")
|
||||
if err != nil {
|
||||
c.JSON(401, resp.CodeMsg(401001, err.Error()))
|
||||
c.JSON(401, resp.CodeMsg(resp.CODE_AUTH, err.Error()))
|
||||
c.Abort() // 停止执行后续的处理函数
|
||||
return
|
||||
}
|
||||
@@ -35,7 +35,7 @@ func AuthorizeOauth2(scope []string) gin.HandlerFunc {
|
||||
// 获取缓存的用户信息
|
||||
info := token.Oauth2InfoGet(claims)
|
||||
if info.ClientId == "" {
|
||||
c.JSON(401, resp.CodeMsg(401002, "invalid login user information"))
|
||||
c.JSON(401, resp.CodeMsg(resp.CODE_AUTH_INVALID, "invalid login user information"))
|
||||
c.Abort() // 停止执行后续的处理函数
|
||||
return
|
||||
}
|
||||
@@ -54,7 +54,7 @@ func AuthorizeOauth2(scope []string) gin.HandlerFunc {
|
||||
}
|
||||
if !hasScope {
|
||||
msg := fmt.Sprintf("unauthorized access %s %s", c.Request.Method, c.Request.RequestURI)
|
||||
c.JSON(403, resp.CodeMsg(403001, msg))
|
||||
c.JSON(403, resp.CodeMsg(resp.CODE_PERMISSION, msg))
|
||||
c.Abort() // 停止执行后续的处理函数
|
||||
return
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ func AuthorizeUser(options map[string][]string) gin.HandlerFunc {
|
||||
// 获取请求头标识信息
|
||||
tokenStr := reqctx.Authorization(c)
|
||||
if tokenStr == "" {
|
||||
c.JSON(401, resp.CodeMsg(401003, "authorization token is empty"))
|
||||
c.JSON(401, resp.CodeMsg(resp.CODE_AUTH_NOTOKEN, "authorization token is empty"))
|
||||
c.Abort() // 停止执行后续的处理函数
|
||||
return
|
||||
}
|
||||
@@ -76,7 +76,7 @@ func AuthorizeUser(options map[string][]string) gin.HandlerFunc {
|
||||
// 验证令牌
|
||||
claims, err := token.UserTokenVerify(tokenStr, "access")
|
||||
if err != nil {
|
||||
c.JSON(401, resp.CodeMsg(401001, err.Error()))
|
||||
c.JSON(401, resp.CodeMsg(resp.CODE_AUTH, err.Error()))
|
||||
c.Abort() // 停止执行后续的处理函数
|
||||
return
|
||||
}
|
||||
@@ -84,7 +84,7 @@ func AuthorizeUser(options map[string][]string) gin.HandlerFunc {
|
||||
// 获取缓存的用户信息
|
||||
info := token.UserInfoGet(claims)
|
||||
if info.UserId <= 0 {
|
||||
c.JSON(401, resp.CodeMsg(401002, "invalid login user information"))
|
||||
c.JSON(401, resp.CodeMsg(resp.CODE_AUTH_INVALID, "invalid login user information"))
|
||||
c.Abort() // 停止执行后续的处理函数
|
||||
return
|
||||
}
|
||||
@@ -100,7 +100,7 @@ func AuthorizeUser(options map[string][]string) gin.HandlerFunc {
|
||||
verifyOk := verifyRolePermission(roles, perms, options)
|
||||
if !verifyOk {
|
||||
msg := fmt.Sprintf("unauthorized access %s %s", c.Request.Method, c.Request.RequestURI)
|
||||
c.JSON(403, resp.CodeMsg(403001, msg))
|
||||
c.JSON(403, resp.CodeMsg(resp.CODE_PERMISSION, msg))
|
||||
c.Abort() // 停止执行后续的处理函数
|
||||
return
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ func OperateLog(options Options) gin.HandlerFunc {
|
||||
// 获取登录用户信息
|
||||
loginUser, err := reqctx.LoginUser(c)
|
||||
if err != nil {
|
||||
c.JSON(401, resp.CodeMsg(401002, i18n.TKey(language, err.Error())))
|
||||
c.JSON(401, resp.CodeMsg(resp.CODE_AUTH_INVALID, i18n.TKey(language, err.Error())))
|
||||
c.Abort() // 停止执行后续的处理函数
|
||||
return
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ func CryptoApi(requestDecrypt, responseEncrypt bool) gin.HandlerFunc {
|
||||
|
||||
// 是否存在data字段数据
|
||||
if contentDe == "" {
|
||||
c.JSON(422, resp.CodeMsg(422002, "decrypt not found field data"))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "decrypt not found field data"))
|
||||
c.Abort() // 停止执行后续的处理函数
|
||||
return
|
||||
}
|
||||
@@ -61,7 +61,7 @@ func CryptoApi(requestDecrypt, responseEncrypt bool) gin.HandlerFunc {
|
||||
dataBodyStr, err := crypto.AESDecryptBase64(contentDe, apiKey)
|
||||
if err != nil {
|
||||
logger.Errorf("CryptoApi decrypt err => %v", err)
|
||||
c.JSON(422, resp.CodeMsg(422001, "decrypted data could not be parsed"))
|
||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, "decrypted data could not be parsed"))
|
||||
c.Abort() // 停止执行后续的处理函数
|
||||
return
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ func OperateLog(options Options) gin.HandlerFunc {
|
||||
// 获取登录用户信息
|
||||
loginUser, err := reqctx.LoginUser(c)
|
||||
if err != nil {
|
||||
c.JSON(401, resp.CodeMsg(401002, "invalid login user information"))
|
||||
c.JSON(401, resp.CodeMsg(resp.CODE_AUTH_INVALID, "invalid login user information"))
|
||||
c.Abort() // 停止执行后续的处理函数
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -12,6 +11,7 @@ import (
|
||||
"be.ems/src/framework/ip2region"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/utils/crypto"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -39,7 +39,7 @@ type LimitOption struct {
|
||||
// 参数表示:5秒内,最多请求10次,限制类型为 IP
|
||||
//
|
||||
// 使用 USER 时,请在用户身份授权认证校验后使用
|
||||
// 以便获取登录用户信息,无用户信息时默认为 GLOBAL
|
||||
// 以便获取登录用户信息,无用户信息时默认为 LIMIT_GLOBAL
|
||||
func RateLimit(option LimitOption) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
// 初始可选参数数据
|
||||
@@ -55,38 +55,38 @@ func RateLimit(option LimitOption) gin.HandlerFunc {
|
||||
|
||||
// 获取执行函数名称
|
||||
funcName := c.HandlerName()
|
||||
lastDotIndex := strings.LastIndex(funcName, "/")
|
||||
funcName = funcName[lastDotIndex+1:]
|
||||
// 生成限流key
|
||||
limitKey := constants.CACHE_RATE_LIMIT + ":" + funcName
|
||||
limitKey := constants.CACHE_RATE_LIMIT + ":" + crypto.MD5(funcName)
|
||||
|
||||
// 用户
|
||||
if option.Type == LIMIT_USER {
|
||||
loginUser, err := reqctx.LoginUser(c)
|
||||
if err != nil {
|
||||
c.JSON(401, resp.CodeMsg(401002, "invalid login user information"))
|
||||
userId := reqctx.LoginUserToUserID(c)
|
||||
if userId <= 0 {
|
||||
c.JSON(401, resp.CodeMsg(resp.CODE_AUTH_INVALID, "invalid login user information"))
|
||||
c.Abort() // 停止执行后续的处理函数
|
||||
return
|
||||
}
|
||||
limitKey = fmt.Sprintf("%s:%d:%s", constants.CACHE_RATE_LIMIT, loginUser.UserId, funcName)
|
||||
funcMd5 := crypto.MD5(fmt.Sprintf("%d:%s", userId, funcName))
|
||||
limitKey = constants.CACHE_RATE_LIMIT + ":" + funcMd5
|
||||
}
|
||||
|
||||
// IP
|
||||
if option.Type == LIMIT_IP {
|
||||
clientIP := ip2region.ClientIP(c.ClientIP())
|
||||
limitKey = constants.CACHE_RATE_LIMIT + ":" + clientIP + ":" + funcName
|
||||
funcMd5 := crypto.MD5(fmt.Sprintf("%s:%s", clientIP, funcName))
|
||||
limitKey = constants.CACHE_RATE_LIMIT + ":" + funcMd5
|
||||
}
|
||||
|
||||
// 在Redis查询并记录请求次数
|
||||
rateCount, err := redis.RateLimit("", limitKey, option.Time, option.Count)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg("access too often, please try again later"))
|
||||
c.JSON(200, resp.CodeMsg(resp.CODE_RATELIMIT, resp.MSG_RATELIMIT))
|
||||
c.Abort() // 停止执行后续的处理函数
|
||||
return
|
||||
}
|
||||
rateTime, err := redis.GetExpire("", limitKey)
|
||||
if err != nil {
|
||||
c.JSON(200, resp.ErrMsg("access too often, please try again later"))
|
||||
c.JSON(200, resp.CodeMsg(resp.CODE_RATELIMIT, resp.MSG_RATELIMIT))
|
||||
c.Abort() // 停止执行后续的处理函数
|
||||
return
|
||||
}
|
||||
@@ -97,7 +97,7 @@ func RateLimit(option LimitOption) gin.HandlerFunc {
|
||||
c.Header("X-RateLimit-Reset", fmt.Sprintf("%d", time.Now().Unix()+rateTime)) // 重置时间戳
|
||||
|
||||
if rateCount >= option.Count {
|
||||
c.JSON(200, resp.ErrMsg("access too often, please try again later"))
|
||||
c.JSON(200, resp.CodeMsg(resp.CODE_RATELIMIT, resp.MSG_RATELIMIT))
|
||||
c.Abort() // 停止执行后续的处理函数
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package middleware
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/utils/crypto"
|
||||
)
|
||||
|
||||
// repeatParam 重复提交参数的类型定义
|
||||
@@ -40,9 +41,12 @@ func RepeatSubmit(interval int64) gin.HandlerFunc {
|
||||
}
|
||||
paramsJSONStr := string(paramsJSONByte)
|
||||
|
||||
// 获取执行函数名称
|
||||
funcName := c.HandlerName()
|
||||
// 唯一标识(指定key + 客户端IP + 请求地址)
|
||||
clientIP := ip2region.ClientIP(c.ClientIP())
|
||||
repeatKey := constants.CACHE_REPEAT_SUBMIT + ":" + clientIP + ":" + c.Request.RequestURI
|
||||
funcMd5 := crypto.MD5(fmt.Sprintf("%s:%s", clientIP, funcName))
|
||||
repeatKey := constants.CACHE_REPEAT_SUBMIT + ":" + funcMd5
|
||||
|
||||
// 在Redis查询并记录请求次数
|
||||
repeatStr, _ := redis.Get("", repeatKey)
|
||||
@@ -56,7 +60,8 @@ func RepeatSubmit(interval int64) gin.HandlerFunc {
|
||||
compareParams := rp.Params == paramsJSONStr
|
||||
|
||||
// 设置重复提交声明响应头(毫秒)
|
||||
c.Header("X-RepeatSubmit-Rest", strconv.FormatInt(time.Now().Add(time.Duration(compareTime)*time.Second).UnixNano()/int64(time.Millisecond), 10))
|
||||
t := time.Now().Add(time.Duration(compareTime) * time.Second)
|
||||
c.Header("X-RepeatSubmit-Rest", fmt.Sprint(t.UnixMilli()))
|
||||
|
||||
// 小于间隔时间且参数内容一致
|
||||
if compareTime < interval && compareParams {
|
||||
|
||||
@@ -1,22 +1,5 @@
|
||||
package resp
|
||||
|
||||
const (
|
||||
// CODE_ERROR 响应-code错误失败
|
||||
CODE_ERROR = 400001
|
||||
// MSG_ERROR 响应-msg错误失败
|
||||
MSG_ERROR = "error"
|
||||
|
||||
// CODE_SUCCESS 响应-msg正常成功
|
||||
CODE_SUCCESS = 200001
|
||||
// MSG_SUCCCESS 响应-code正常成功
|
||||
MSG_SUCCCESS = "success"
|
||||
|
||||
// 响应-code加密数据
|
||||
CODE_ENCRYPT = 200999
|
||||
// 响应-msg加密数据
|
||||
MSG_ENCRYPT = "encrypt"
|
||||
)
|
||||
|
||||
// Resp 响应结构体
|
||||
type Resp struct {
|
||||
Code int `json:"code"` // 响应状态码
|
||||
|
||||
78
src/framework/resp/code.go
Normal file
78
src/framework/resp/code.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package resp
|
||||
|
||||
// |HTTP|状态码|描述|排查建议|
|
||||
// |----|----|----|----|
|
||||
// |500 |500001 |internal error|服务内部错误|
|
||||
// |200 |200999 |encrypt|正常请求加密数据|
|
||||
// |200 |200001 |request success|正常请求成功|
|
||||
// |200 |400001 |exist error|正常请求错误信息|
|
||||
// |200 |400002 |ratelimit over|请求限流|
|
||||
// |401 |401001 |authentication error|身份认证失败或者过期|
|
||||
// |401 |401002 |authentication invalid error|无效身份信息|
|
||||
// |401 |401003 |authorization token error|令牌字符为空|
|
||||
// |401 |401004 |device fingerprint mismatch|设备指纹信息不匹配|
|
||||
// |403 |403001 |permission error|权限未分配|
|
||||
// |422 |422001 |params error|参数接收解析错误|
|
||||
// |422 |422002 |params error|参数属性传入错误|
|
||||
|
||||
// ====== 500 ======
|
||||
const (
|
||||
// CODE_ERROR_INTERNAL 响应-code服务内部错误
|
||||
CODE_INTERNAL = 500001
|
||||
// MSG_ERROR_INTERNAL 响应-msg服务内部错误
|
||||
MSG_INTERNAL = "internal error"
|
||||
)
|
||||
|
||||
// ====== 200 ======
|
||||
const (
|
||||
// CODE_ENCRYPT 响应-code加密数据
|
||||
CODE_ENCRYPT = 200999
|
||||
// MSG_ENCRYPT 响应-msg加密数据
|
||||
MSG_ENCRYPT = "encrypt"
|
||||
|
||||
// CODE_SUCCESS 响应-code正常成功
|
||||
CODE_SUCCESS = 200001
|
||||
// MSG_SUCCCESS 响应-msg正常成功
|
||||
MSG_SUCCCESS = "success"
|
||||
|
||||
// CODE_ERROR 响应-code错误失败
|
||||
CODE_ERROR = 400001
|
||||
// MSG_ERROR 响应-msg错误失败
|
||||
MSG_ERROR = "error"
|
||||
|
||||
// CODE_RATELIMIT 响应-code错误失败
|
||||
CODE_RATELIMIT = 400002
|
||||
// MSG_RATELIMIT 响应-msg错误失败
|
||||
MSG_RATELIMIT = "access too often, please try again later"
|
||||
)
|
||||
|
||||
// ====== 401 ======
|
||||
const (
|
||||
// CODE_ERROR 响应-code身份认证失败或者过期
|
||||
CODE_AUTH = 401001
|
||||
|
||||
// CODE_AUTH_INVALID 响应-code无效身份信息
|
||||
CODE_AUTH_INVALID = 401002
|
||||
|
||||
// CODE_AUTH_NOTOKEN 响应-code令牌字符为空
|
||||
CODE_AUTH_NOTOKEN = 401003
|
||||
|
||||
// CODE_AUTH_DEVICE 响应-code设备指纹信息不匹配
|
||||
CODE_AUTH_DEVICE = 401004
|
||||
// MSG_AUTH_DEVICE 响应-msg设备指纹信息不匹配
|
||||
MSG_AUTH_DEVICE = "device fingerprint mismatch"
|
||||
)
|
||||
|
||||
// ====== 403 ======
|
||||
const (
|
||||
// CODE_PERMISSION 响应-code权限未分配
|
||||
CODE_PERMISSION = 403001
|
||||
)
|
||||
|
||||
// ====== 422 ======
|
||||
const (
|
||||
// CODE_PARAM_PARSER 响应-code参数接收解析错误
|
||||
CODE_PARAM_PARSER = 422001
|
||||
// CODE_PARAM_CHEACK 响应-code参数属性传入错误
|
||||
CODE_PARAM_CHEACK = 422002
|
||||
)
|
||||
Reference in New Issue
Block a user