70 lines
2.1 KiB
Go
70 lines
2.1 KiB
Go
package middleware
|
|
|
|
import (
|
|
"net/http"
|
|
"runtime/debug"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.iwork-ai.com/xdc/iqudo-top1/internal/auth"
|
|
"git.iwork-ai.com/xdc/iqudo-top1/internal/response"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
func RequestLogger(log *zap.Logger) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
started := time.Now()
|
|
requestID := c.GetHeader("X-Request-ID")
|
|
if requestID == "" {
|
|
requestID = uuid.NewString()
|
|
}
|
|
c.Set("request_id", requestID)
|
|
c.Header("X-Request-ID", requestID)
|
|
c.Next()
|
|
|
|
fields := []zap.Field{
|
|
zap.String("request_id", requestID), zap.String("method", c.Request.Method), zap.String("path", c.Request.URL.Path),
|
|
zap.Int("status", c.Writer.Status()), zap.Int("response_bytes", c.Writer.Size()), zap.Duration("duration", time.Since(started)), zap.String("client_ip", c.ClientIP()),
|
|
}
|
|
if principal, ok := auth.PrincipalFromContext(c); ok {
|
|
fields = append(fields, zap.Uint64("tenant_id", principal.TenantID), zap.Uint64("user_id", principal.UserID))
|
|
}
|
|
if len(c.Errors) > 0 {
|
|
fields = append(fields, zap.String("errors", c.Errors.String()))
|
|
}
|
|
log.Info("http request", fields...)
|
|
}
|
|
}
|
|
|
|
func Recovery(log *zap.Logger) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
defer func() {
|
|
if recovered := recover(); recovered != nil {
|
|
log.Error("panic recovered", zap.Any("panic", recovered), zap.ByteString("stack", debug.Stack()))
|
|
response.Error(c, http.StatusInternalServerError, "INTERNAL_ERROR", "服务暂时不可用")
|
|
}
|
|
}()
|
|
c.Next()
|
|
}
|
|
}
|
|
|
|
func Authenticate(service *auth.Service) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
header := c.GetHeader("Authorization")
|
|
parts := strings.SplitN(header, " ", 2)
|
|
if len(parts) != 2 || !strings.EqualFold(parts[0], "Bearer") {
|
|
response.Error(c, http.StatusUnauthorized, "UNAUTHORIZED", "请先登录")
|
|
return
|
|
}
|
|
principal, err := service.ParseAccessToken(parts[1])
|
|
if err != nil {
|
|
response.Error(c, http.StatusUnauthorized, "INVALID_TOKEN", "登录状态已失效")
|
|
return
|
|
}
|
|
auth.SetPrincipal(c, principal)
|
|
c.Next()
|
|
}
|
|
}
|