fix(iap): 修复JWS验证逻辑,支持原始R||S签名格式
Build docker and publish / build (20.15.1) (push) Successful in 6m38s

fix(middleware): 增加设备中间件的日志记录
fix(auth): 优化认证中间件的错误日志记录
feat(iap): 添加苹果交易附加逻辑的详细日志
This commit is contained in:
2025-12-15 23:44:55 -08:00
parent 3c6dd5058b
commit e11ed2338d
4 changed files with 75 additions and 31 deletions
+7 -6
View File
@@ -27,7 +27,7 @@ func AuthMiddleware(svc *svc.ServiceContext) func(c *gin.Context) {
// get token from header
token := c.GetHeader("Authorization")
if token == "" {
logger.WithContext(c.Request.Context()).Debug("[AuthMiddleware] Token Empty")
logger.WithContext(c.Request.Context()).Errorw("[AuthMiddleware] token empty", logger.Field("path", c.Request.URL.Path))
result.HttpResult(c, nil, errors.Wrapf(xerr.NewErrCode(xerr.ErrorTokenEmpty), "Token Empty"))
c.Abort()
return
@@ -35,7 +35,7 @@ func AuthMiddleware(svc *svc.ServiceContext) func(c *gin.Context) {
// parse token
claims, err := jwt.ParseJwtToken(token, jwtConfig.AccessSecret)
if err != nil {
logger.WithContext(c.Request.Context()).Debug("[AuthMiddleware] ParseJwtToken", logger.Field("error", err.Error()), logger.Field("token", token))
logger.WithContext(c.Request.Context()).Errorw("[AuthMiddleware] parse token failed", logger.Field("error", err.Error()))
result.HttpResult(c, nil, errors.Wrapf(xerr.NewErrCode(xerr.ErrorTokenExpire), "Token Invalid"))
c.Abort()
return
@@ -53,7 +53,7 @@ func AuthMiddleware(svc *svc.ServiceContext) func(c *gin.Context) {
sessionIdCacheKey := fmt.Sprintf("%v:%v", config.SessionIdKey, sessionId)
value, err := svc.Redis.Get(c, sessionIdCacheKey).Result()
if err != nil {
logger.WithContext(c.Request.Context()).Debug("[AuthMiddleware] Redis Get", logger.Field("error", err.Error()), logger.Field("sessionId", sessionId))
logger.WithContext(c.Request.Context()).Errorw("[AuthMiddleware] redis get failed", logger.Field("error", err.Error()), logger.Field("sessionId", sessionId))
result.HttpResult(c, nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidAccess), "Invalid Access"))
c.Abort()
return
@@ -61,7 +61,7 @@ func AuthMiddleware(svc *svc.ServiceContext) func(c *gin.Context) {
//verify user id
if value != fmt.Sprintf("%v", userId) {
logger.WithContext(c.Request.Context()).Debug("[AuthMiddleware] Invalid Access", logger.Field("userId", userId), logger.Field("sessionId", sessionId))
logger.WithContext(c.Request.Context()).Errorw("[AuthMiddleware] user mismatch", logger.Field("userId", userId), logger.Field("sessionId", sessionId), logger.Field("value", value))
result.HttpResult(c, nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidAccess), "Invalid Access"))
c.Abort()
return
@@ -69,7 +69,7 @@ func AuthMiddleware(svc *svc.ServiceContext) func(c *gin.Context) {
userInfo, err := svc.UserModel.FindOne(c, userId)
if err != nil {
logger.WithContext(c.Request.Context()).Debug("[AuthMiddleware] UserModel FindOne", logger.Field("error", err.Error()), logger.Field("userId", userId))
logger.WithContext(c.Request.Context()).Errorw("[AuthMiddleware] user find failed", logger.Field("error", err.Error()), logger.Field("userId", userId))
result.HttpResult(c, nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "Database Query Error"))
c.Abort()
return
@@ -77,11 +77,12 @@ func AuthMiddleware(svc *svc.ServiceContext) func(c *gin.Context) {
// admin verify
paths := strings.Split(c.Request.URL.Path, "/")
if tool.StringSliceContains(paths, "admin") && !*userInfo.IsAdmin {
logger.WithContext(c.Request.Context()).Debug("[AuthMiddleware] Not Admin User", logger.Field("userId", userId), logger.Field("sessionId", sessionId))
logger.WithContext(c.Request.Context()).Errorw("[AuthMiddleware] not admin", logger.Field("userId", userId), logger.Field("sessionId", sessionId))
result.HttpResult(c, nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidAccess), "Invalid Access"))
c.Abort()
return
}
logger.WithContext(c.Request.Context()).Infow("[AuthMiddleware] auth ok", logger.Field("userId", userId), logger.Field("loginType", loginType), logger.Field("path", c.Request.URL.Path))
ctx = context.WithValue(ctx, constant.LoginType, loginType)
ctx = context.WithValue(ctx, constant.CtxKeyUser, userInfo)
ctx = context.WithValue(ctx, constant.CtxKeySessionID, sessionId)
+11
View File
@@ -14,6 +14,7 @@ import (
"github.com/perfect-panel/server/internal/svc"
pkgaes "github.com/perfect-panel/server/pkg/aes"
"github.com/perfect-panel/server/pkg/constant"
"github.com/perfect-panel/server/pkg/logger"
"github.com/perfect-panel/server/pkg/result"
"github.com/perfect-panel/server/pkg/xerr"
"github.com/pkg/errors"
@@ -30,11 +31,13 @@ func DeviceMiddleware(srvCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
if !srvCtx.Config.Device.Enable {
logger.WithContext(c.Request.Context()).Infow("[DeviceMiddleware] disabled")
c.Next()
return
}
if srvCtx.Config.Device.SecuritySecret == "" {
logger.WithContext(c.Request.Context()).Errorw("[DeviceMiddleware] secret empty")
result.HttpResult(c, nil, errors.Wrapf(xerr.NewErrCode(xerr.SecretIsEmpty), "Secret is empty"))
c.Abort()
return
@@ -48,12 +51,14 @@ func DeviceMiddleware(srvCtx *svc.ServiceContext) func(c *gin.Context) {
loginType, ok := ctx.Value(constant.LoginType).(string)
if !ok || loginType != "device" {
logger.WithContext(c.Request.Context()).Infow("[DeviceMiddleware] skip encryption", logger.Field("loginType", loginType))
c.Next()
return
}
rw := NewResponseWriter(c, srvCtx)
if !rw.Decrypt() {
logger.WithContext(c.Request.Context()).Errorw("[DeviceMiddleware] decrypt failed", logger.Field("path", c.Request.URL.Path))
result.HttpResult(c, nil, errors.Wrapf(xerr.NewErrCode(xerr.InvalidCiphertext), "Invalid ciphertext"))
c.Abort()
return
@@ -125,6 +130,7 @@ func (rw *ResponseWriter) Decrypt() bool {
params := map[string]interface{}{}
err = json.Unmarshal([]byte(decrypt), &params)
if err == nil {
logger.WithContext(rw.c.Request.Context()).Infow("[DeviceMiddleware] query decrypt ok", logger.Field("path", rw.c.Request.URL.Path))
for k, v := range params {
query.Set(k, fmt.Sprintf("%v", v))
}
@@ -151,23 +157,28 @@ func (rw *ResponseWriter) Decrypt() bool {
data := params["data"]
nonce := params["time"]
if err != nil || data == nil {
logger.WithContext(rw.c.Request.Context()).Errorw("[DeviceMiddleware] body parse failed", logger.Field("error", err))
return false
}
str, ok := data.(string)
if !ok {
logger.WithContext(rw.c.Request.Context()).Errorw("[DeviceMiddleware] body data type invalid")
return false
}
iv, ok := nonce.(string)
if !ok {
logger.WithContext(rw.c.Request.Context()).Errorw("[DeviceMiddleware] body time type invalid")
return false
}
decrypt, err := pkgaes.Decrypt(str, rw.encryptionKey, iv)
if err != nil {
logger.WithContext(rw.c.Request.Context()).Errorw("[DeviceMiddleware] body decrypt error", logger.Field("error", err.Error()))
return false
}
rw.c.Request.Body = io.NopCloser(bytes.NewBuffer([]byte(decrypt)))
logger.WithContext(rw.c.Request.Context()).Infow("[DeviceMiddleware] body decrypt ok", logger.Field("path", rw.c.Request.URL.Path))
return true
}