feat: 同步 huangguo2-server 的 11 个非基线提交
按意图重做在 huakui 代码底: - 删除数据埋点逻辑:移除 pub/dataReport、reportser、srv_report、 eventmod、上报定时任务及注册/登录/点赞/收藏/评论/解锁/订单处的 上报调用和 reportSdkConfig 配置下发 - app 认证改为按设备ID识别用户:去掉 token 校验、Register/Login/ ResetPassword/GuestLogin 接口,新增 ResolveDeviceUser 和设备缓存 - 广告改为按 AppId 从媒资中心拉取:pub/storage 新增 QueryAdvitise, UpdateAdvitiseData 替代 UpdateAdvitiseDataFromJt - 后台登录取消谷歌二次验证,密码正确即登录 - 短剧/专题 slug 改为 10 位大小写字母+数字混合 - 本地 app.yaml/web.yaml 保留 HKDJNET_* 模板(不提交生产凭据) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+30
-122
@@ -1,137 +1,45 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"hkdj-web-server/app/appg"
|
||||
"hkdj-web-server/pub/common/enum/consts"
|
||||
"hkdj-web-server/pub/common/log"
|
||||
"hkdj-web-server/pub/common/srvdef"
|
||||
"hkdj-web-server/pub/common/utils"
|
||||
"hkdj-web-server/pub/pubdef"
|
||||
"net/http"
|
||||
"strings"
|
||||
"hkdj-web-server/app/middleware/reptilerecord"
|
||||
"hkdj-web-server/app/service/authser"
|
||||
"hkdj-web-server/pub/common"
|
||||
"hkdj-web-server/pub/common/enum/consts"
|
||||
"hkdj-web-server/pub/common/ipaddr"
|
||||
"hkdj-web-server/pub/common/log"
|
||||
"hkdj-web-server/pub/common/srvdef"
|
||||
"hkdj-web-server/pub/pubdef"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// gin 验证中间件
|
||||
|
||||
var (
|
||||
// 白名单,不需要验证token的api
|
||||
whiteList = []string{
|
||||
"/api/app/auth/guest",
|
||||
"/api/app/auth/register",
|
||||
"/api/app/auth/login",
|
||||
"/api/app/auth/resetPassword",
|
||||
"/api/app/video/all/list",
|
||||
"/api/app/video/topic/list",
|
||||
"/api/app/video/list",
|
||||
"/api/app/video/detail",
|
||||
"/api/app/playlet/home",
|
||||
"/api/app/playlet/all/list",
|
||||
"/api/app/playlet/topic/list",
|
||||
"/api/app/playlet/topic/detail",
|
||||
"/api/app/playlet/operate/list",
|
||||
"/api/app/playlet/rank",
|
||||
"/api/app/playlet/hot/rank/list",
|
||||
"/api/app/playlet/today-update",
|
||||
"/api/app/playlet/tag/options",
|
||||
"/api/app/playlet/tag/list",
|
||||
"/api/app/playlet/guess-like/list",
|
||||
"/api/app/playlet/search",
|
||||
"/api/app/playlet/hot-like",
|
||||
"/api/app/playlet/detail",
|
||||
"/api/app/playlet/chapter/detail",
|
||||
"/api/app/recharge/package/list",
|
||||
"/api/app/comment/list",
|
||||
"/api/app/theme/list",
|
||||
"/api/app/config/info",
|
||||
"/api/app/config/footer/info",
|
||||
"/api/app/config/richtext/list",
|
||||
"/api/app/applist",
|
||||
"/api/app/translation/category/list",
|
||||
"/api/app/navigation/header",
|
||||
"/api/app/health/ping",
|
||||
"/api/app/statcenter/sync",
|
||||
"/h5/m3u8",
|
||||
"/enkey",
|
||||
"/newenkey",
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
tokener = utils.NewTokenRedis()
|
||||
)
|
||||
|
||||
// gin 用户识别中间件:不再校验 token,按 X-User-Agent 中的 devID 识别用户,
|
||||
// 该设备首次访问时自动创建用户。没有 devID 的请求按匿名处理,
|
||||
// 需要用户身份的接口自行返回"请先登录"。
|
||||
func Auth(ctx *gin.Context) {
|
||||
dotoken := func() srvdef.CodeType {
|
||||
token := ctx.Request.Header.Get("Authorization")
|
||||
// 去掉Bearer,如果有
|
||||
token = utils.StripBearerPrefixFromTokenString(token)
|
||||
|
||||
if token == "" {
|
||||
for _, w := range whiteList {
|
||||
if strings.Contains(ctx.Request.URL.Path, w) {
|
||||
return srvdef.Success
|
||||
}
|
||||
}
|
||||
|
||||
log.Error("Auth:token is empty", log.Any("sysType", ctx.GetString(consts.CtxSysType)))
|
||||
return srvdef.InvalidToken
|
||||
}
|
||||
|
||||
userId, newToken, err := utils.ParseUserToken(token, appg.Conf.JwtKey)
|
||||
if err != nil {
|
||||
for _, w := range whiteList {
|
||||
if strings.Contains(ctx.Request.URL.Path, w) {
|
||||
return srvdef.Success
|
||||
}
|
||||
}
|
||||
|
||||
log.Error("Auth:ParseUserToken", log.Any("token", token), log.E(err))
|
||||
return srvdef.InvalidToken
|
||||
}
|
||||
|
||||
if pubdef.IsCrawlerUser(userId) {
|
||||
if len(newToken) > 0 {
|
||||
ctx.Writer.Header().Set("Refresh-Authorization", newToken)
|
||||
}
|
||||
ctx.Set(consts.CtxUserID, userId)
|
||||
ctx.Set(consts.CtxToken, token)
|
||||
return srvdef.Success
|
||||
}
|
||||
|
||||
has, err := tokener.Exists(userId, token)
|
||||
if err != nil {
|
||||
log.Error("Auth:Exists", log.Any("userId", userId), log.Any("token", token), log.E(err))
|
||||
return srvdef.InvalidToken
|
||||
}
|
||||
if !has {
|
||||
log.Error("Auth:Exists:token not exists", log.Any("userId", userId), log.Any("token", token), log.E(err))
|
||||
return srvdef.InvalidToken
|
||||
}
|
||||
|
||||
if len(newToken) > 0 {
|
||||
err = tokener.Save(userId, newToken)
|
||||
if err != nil {
|
||||
log.Error("Auth:Save", log.Any("userId", userId), log.Any("token", newToken), log.E(err))
|
||||
return srvdef.StoreLevel
|
||||
}
|
||||
ctx.Writer.Header().Set("Refresh-Authorization", newToken)
|
||||
}
|
||||
|
||||
ctx.Set(consts.CtxUserID, userId)
|
||||
ctx.Set(consts.CtxToken, token)
|
||||
|
||||
return srvdef.Success
|
||||
if reptilerecord.IsBot(ctx) {
|
||||
ctx.Set(consts.CtxUserID, pubdef.CrawlerUserId)
|
||||
return
|
||||
}
|
||||
|
||||
errType := dotoken()
|
||||
if errType != srvdef.Success {
|
||||
// log.Info("Auth bad request", log.Any("Path", ctx.Request.URL.Path), log.Any("ip", ctx.ClientIP()))
|
||||
ctx.AbortWithStatusJSON(http.StatusOK, gin.H{
|
||||
"code": errType,
|
||||
"msg": errType.Msg(),
|
||||
})
|
||||
ua, err := common.GetUA(ctx)
|
||||
if err != nil || strings.TrimSpace(ua.DevID) == "" {
|
||||
return
|
||||
}
|
||||
|
||||
userId, serr := authser.ResolveDeviceUser(ctx, ua, ipaddr.ResolveClientIP(ctx), ctx.GetHeader("channel"))
|
||||
if serr != nil {
|
||||
if serr.Code == srvdef.AccountErrAccessForbid {
|
||||
ctx.AbortWithStatusJSON(http.StatusOK, gin.H{
|
||||
"code": serr.Code,
|
||||
"msg": serr.Code.Msg(),
|
||||
})
|
||||
return
|
||||
}
|
||||
log.Error("Auth:ResolveDeviceUser", log.Any("devID", ua.DevID), log.Any("path", ctx.Request.URL.Path), log.E(serr))
|
||||
return
|
||||
}
|
||||
ctx.Set(consts.CtxUserID, userId)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user