feat: 添加 JWT 鉴权拒绝日志
This commit is contained in:
@@ -5,6 +5,8 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/hhs/camtalk/internal/trace"
|
||||
)
|
||||
|
||||
// contextKey 用于在 Gin context 中存储 Claims 的 key。
|
||||
@@ -17,8 +19,13 @@ const (
|
||||
// 校验成功后将 user_id 和 username 写入 Gin Context。
|
||||
func AuthMiddleware(tokenMgr *TokenManager) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
log := trace.FromContext(c.Request.Context())
|
||||
authHeader := c.GetHeader("Authorization")
|
||||
if authHeader == "" {
|
||||
log.Warnw("auth rejected",
|
||||
"client_ip", c.ClientIP(),
|
||||
"path", c.Request.URL.Path,
|
||||
"reason", "missing authorization header")
|
||||
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
|
||||
"code": "INVALID_TOKEN",
|
||||
"message": "missing authorization header",
|
||||
@@ -29,6 +36,10 @@ func AuthMiddleware(tokenMgr *TokenManager) gin.HandlerFunc {
|
||||
// 提取 Bearer token
|
||||
parts := strings.SplitN(authHeader, " ", 2)
|
||||
if len(parts) != 2 || !strings.EqualFold(parts[0], "Bearer") {
|
||||
log.Warnw("auth rejected",
|
||||
"client_ip", c.ClientIP(),
|
||||
"path", c.Request.URL.Path,
|
||||
"reason", "invalid authorization format")
|
||||
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
|
||||
"code": "INVALID_TOKEN",
|
||||
"message": "invalid authorization format",
|
||||
@@ -38,6 +49,11 @@ func AuthMiddleware(tokenMgr *TokenManager) gin.HandlerFunc {
|
||||
|
||||
claims, err := tokenMgr.ValidateAccess(parts[1])
|
||||
if err != nil {
|
||||
log.Warnw("auth rejected",
|
||||
"client_ip", c.ClientIP(),
|
||||
"path", c.Request.URL.Path,
|
||||
"reason", "invalid or expired token",
|
||||
"error", err)
|
||||
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
|
||||
"code": "INVALID_TOKEN",
|
||||
"message": "invalid or expired token",
|
||||
|
||||
Reference in New Issue
Block a user