fix(file): 修复商品详情截图与提现打款凭证等私有图片 403 权限问题
- 放宽公开商品截图 key 提取规则,支持任意合规 object key 转换为免鉴权公开端点 - 补充后台截图上传 listing_screenshot 与 operating-expense 场景识别 - dependencies 授权器支持已审核上架商品截图兜底放行、提现人打款凭证鉴权及变体后缀匹配 - /api/files 路由组支持用户与管理员双重鉴权 (AuthUserOrAdmin) - 前端收款账号凭证与提现详情凭证统一升级为 AuthImage 组件并支持大图预览
This commit is contained in:
@@ -96,6 +96,73 @@ func Auth(jwtManager *auth.JWTManager, validate UserTokenValidatorFunc) gin.Hand
|
||||
}
|
||||
}
|
||||
|
||||
// AuthUserOrAdmin 允许普通用户或管理员访问共享资源(如私有文件流)。
|
||||
func AuthUserOrAdmin(jwtManager *auth.JWTManager, userValidate UserTokenValidatorFunc, adminValidate AdminTokenValidatorFunc) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
// 1. 优先尝试管理员鉴权(Header Bearer 或 Admin Cookie)
|
||||
if tokenText, tokenSource := extractAdminToken(c); tokenText != "" {
|
||||
if claims, err := jwtManager.ParseSubject(tokenText, "access", "admin"); err == nil {
|
||||
username := claims.Phone
|
||||
passwordMustChange := false
|
||||
validAdmin := true
|
||||
if adminValidate != nil {
|
||||
tokenContext, err := adminValidate(c.Request.Context(), claims.UserID, claims.TokenVersion)
|
||||
if err != nil {
|
||||
RecordAdminAuthFailure(c, "invalid", tokenSource, 0, 0)
|
||||
validAdmin = false
|
||||
} else {
|
||||
username = tokenContext.Username
|
||||
passwordMustChange = tokenContext.PasswordMustChange
|
||||
}
|
||||
}
|
||||
if validAdmin {
|
||||
c.Set(ContextAdminID, claims.UserID)
|
||||
c.Request = c.Request.WithContext(logging.WithAdminID(c.Request.Context(), claims.UserID))
|
||||
c.Set(ContextUsername, username)
|
||||
c.Set(ContextPasswordMustChange, passwordMustChange)
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 尝试普通用户鉴权(Header Bearer 或 User Cookie)
|
||||
tokenText := extractBearerToken(c)
|
||||
if tokenText == "" {
|
||||
if cookieToken, err := c.Cookie(UserAccessCookieName); err == nil {
|
||||
tokenText = strings.TrimSpace(cookieToken)
|
||||
}
|
||||
}
|
||||
if tokenText == "" {
|
||||
response.Unauthorized(c, "缺少访问令牌")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
claims, err := jwtManager.ParseSubject(tokenText, "access", "user")
|
||||
if err != nil {
|
||||
response.Unauthorized(c, "访问令牌无效或已过期")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
if userValidate != nil {
|
||||
if err := userValidate(c.Request.Context(), claims.UserID, claims.TokenVersion); err != nil {
|
||||
if errors.Is(err, auth.ErrDependencyUnavailable) {
|
||||
response.ServiceUnavailable(c, "用户认证服务暂时不可用")
|
||||
} else {
|
||||
response.Unauthorized(c, "登录状态已失效,请重新登录")
|
||||
}
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.Set(ContextUserID, claims.UserID)
|
||||
c.Set(ContextPhone, claims.Phone)
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func AdminAuth(jwtManager *auth.JWTManager, validate AdminTokenValidatorFunc) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
tokenText, tokenSource := extractAdminToken(c)
|
||||
|
||||
Reference in New Issue
Block a user