Files
rootandClaude Opus 4.7 f037f11850 feat(adcenter): 新增 POST /api/app/ads/click 广告点击上报到广告中心
- 新增 configser.AdvertiseClickCenter / AsyncAdvertiseClick
- 新增 adsapi.Click handler,接收 AdsClickReq{adsId, location},异步转发
- 走广告中心 ${versionUrl}/api/stat/advitise/v2/click,appId=12
- 鉴权白名单放行

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-10-29 16:19:35 +08:00

134 lines
3.3 KiB
Go

package auth
import (
"net/http"
"strings"
"videoweb/app/appg"
"videoweb/pub/common/enum/consts"
"videoweb/pub/common/log"
"videoweb/pub/common/srvdef"
"videoweb/pub/common/utils"
"videoweb/pub/pubdef"
"github.com/gin-gonic/gin"
)
// gin 验证中间件
var (
// 白名单,不需要验证token的api
whiteList = []string{
"/swagger",
"/api/app/auth/guest",
"/api/app/auth/register",
"/api/app/auth/login",
"/api/app/auth/resetPassword",
"/api/app/playlet/home",
"/api/app/playlet/all/list",
"/api/app/playlet/hot/list",
"/api/app/playlet/topic/list",
"/api/app/playlet/topic/detail",
"/api/app/playlet/hot/rank/list",
"/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",
"/api/app/ads/click",
"/h5/m3u8",
"/enkey",
"/newenkey",
}
)
var (
tokener = utils.NewTokenRedis()
)
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
}
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(),
})
}
}