Files
kami_backend/internal/middleware/auth.go
danial 3588bf9af6 feat(camel_oil): 支持Token管理与卡密绑定功能
- 新增CamelOilToken和CamelOilCardBinding数据库表,实现Token及卡密绑定记录管理
- 在service层增加Token的创建、查询、更新、删除及分页功能
- 实现卡密与Token绑定的业务逻辑,支持基于Token的卡密管理
- 在API层新增Token和卡密绑定相关接口:创建Token、获取Token详情、删除Token、列出Token及根据Token查询绑定卡密
- camel_oil_api新增绑卡接口,支持绑卡状态分类及错误处理
- 在定时任务中增加卡密绑定任务,实现自动处理已支付订单的卡密绑定
- 优化订单提交及支付流程,包含日志调整和请求参数随机扰动
- 统一调整camel_oil模块多控制器实现,完成账号状态查询及订单相关接口实现
- 注册更多camel_oil定时任务,包括订单支付检查、账号日重置和待回调订单处理任务
2025-11-23 00:08:35 +08:00

167 lines
5.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package middleware
import (
"net"
"slices"
"time"
"github.com/duke-git/lancet/v2/netutil"
"github.com/gogf/gf/v2/encoding/gjson"
"kami/internal/errHandler"
"kami/internal/service"
"github.com/gogf/gf/v2/container/gset"
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/glog"
"github.com/gogf/gf/v2/text/gstr"
"kami/utility/token"
"kami/utility/verify"
)
// whiteListAuth 白名单中间件
func whiteListAuth(r *ghttp.Request) gcode.Code {
whiteList := []string{
"/api/merchant/order/query",
"/api/restriction/block/order",
"/api/restriction/location/checkIPAllowed",
"/api/cardInfo/appleCard/submit",
"/api/cardInfo/appleCard/rechargeOrder/handler",
"/api/cardInfo/appleCard/query",
"/api/cardInfo/walmart/account/load",
"/api/cardInfo/appleCard/rechargeOrder/callback",
"/api/recharge/tMallGame/agiso/callback",
"/api/recharge/tMallGame/account/getOneByRandom",
"/api/recharge/tMallGame/order/submit",
"/api/recharge/tMallGame/account/auth/callback",
"/api/recharge/tMallGame/data/sync",
"/api/recharge/tMallGame/order/queryOne",
"/api/cardInfo/JDCard/order/submit",
"/api/cardInfo/walmart/order/submit",
"/api/cardInfo/cTrip/order/submit",
"/api/restriction/collection/userInfo",
"/api/restriction/collection/userInfo",
"/api/cookieInfo/jd/order/placeOrder",
"/api/jd-cookie/order/create",
"/api/jd-v2/order/submit",
}
internalWhiteListAuth := []string{
"/api/aes/encryption/params",
}
// 判断 ip
if slices.Contains(internalWhiteListAuth, r.URL.Path) && netutil.IsInternalIP(net.ParseIP(r.GetClientIp())) {
return gcode.CodeOK
}
whiteSet := gset.NewStrSet(true)
whiteSet.Add(whiteList...)
if whiteSet.Contains(r.URL.Path) {
return gcode.CodeOK
}
return gcode.CodeNotAuthorized
}
func loginAuth(r *ghttp.Request) gcode.Code {
// 获取Token
tokenStr := token.GetRequestToken(r)
if tokenStr == "" {
return gcode.New(errHandler.ErrTokenError.Code(), "获取Token失败", nil)
}
userToken, err := token.ParseUserToken(r.GetCtx(), tokenStr)
if err != nil {
glog.Error(r.GetCtx(), "校验Token失败当前Token", tokenStr, "错误码:", err)
return gcode.New(errHandler.ErrTokenError.Code(), "校验Token失败", nil)
}
// 查看redis中是否有token
oldTokenStr, err := token.GetTokenFromRedis(r.GetCtx(), userToken.UserID, userToken.ID)
if err != nil {
glog.Error(r.GetCtx(), "校验Token失败", err)
return gcode.New(errHandler.ErrTokenError.Code(), "校验Token失败", nil)
}
if oldTokenStr != tokenStr {
glog.Error(r.GetCtx(), "校验Token失败", err)
return gcode.New(errHandler.ErrTokenError.Code(), "当前Token失效", nil)
}
// 续签token
newToken, err := token.RefreshUserToken(r.GetCtx(), *userToken)
if err != nil {
glog.Error(r.GetCtx(), "续签Token失败", err)
return gcode.New(errHandler.ErrTokenError.Code(), "续签Token失败", nil)
}
if newToken != "" {
r.Response.Header().Set("refresh-token", newToken)
}
return gcode.CodeOK
}
func iFrameAuth(r *ghttp.Request) gcode.Code {
tokenStr := token.GetRequestToken(r)
if tokenStr == "" {
return gcode.New(errHandler.ErrTokenError.Code(), "Token不存在,请刷新页面!", nil)
}
ctx := r.GetCtx()
frontendModel, err := service.SysConfigDict().GetAESKeyBytes(ctx)
if err != nil {
return gcode.New(errHandler.ErrTokenError.Code(), "解析Token错误!", nil)
}
tokenByte, err := verify.AesCBCURLDecryptWithBase64(tokenStr, frontendModel.Key, frontendModel.IV)
if err != nil {
glog.Error(ctx, "解析Token错误", tokenStr, err)
return gcode.New(errHandler.ErrTokenError.Code(), "Token格式错误!", nil)
}
tokenStruct := struct {
CurrentTime int64 `json:"currentTime"`
UserId string `json:"userId"`
UserAuth string `json:"userAuth"`
}{}
if err = gjson.DecodeTo(tokenByte, &tokenStruct); err != nil {
glog.Error(ctx, "解析Token错误", tokenStr, err)
return gcode.New(errHandler.ErrTokenError.Code(), "Token格式错误!", nil)
}
if time.Since(time.Unix(tokenStruct.CurrentTime, 0)) > time.Minute*30 {
return gcode.New(errHandler.ErrTokenError.Code(), "token失效请刷新页面!", nil)
}
return gcode.CodeOK
}
func LoginOrIframeAuth(r *ghttp.Request) {
if whiteListAuth(r) == gcode.CodeOK {
r.Middleware.Next()
return
}
tokenFrom := r.Request.Header.Get("tokenFrom")
if gstr.ToLower(tokenFrom) == "login" {
code := loginAuth(r)
if code != gcode.CodeOK {
r.Response.WriteJson(ghttp.DefaultHandlerResponse{
Code: code.Code(),
Message: code.Message(),
Data: code.Detail(),
})
return
}
r.Middleware.Next()
return
}
if gstr.ToLower(tokenFrom) == "iframe" {
code := iFrameAuth(r)
if code != gcode.CodeOK {
r.Response.WriteJson(ghttp.DefaultHandlerResponse{
Code: code.Code(),
Message: code.Message(),
Data: code.Detail(),
})
return
}
r.Middleware.Next()
return
}
r.Response.WriteJson(ghttp.DefaultHandlerResponse{
Code: errHandler.ErrTokenError.Code(),
Message: "token来源不明",
})
}