Files
pig-farm-controller/internal/app/middleware/auth.go
2025-10-30 16:35:54 +08:00

61 lines
2.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Package middleware 存放中间件
package middleware
import (
"errors"
"net/http"
"strings"
"git.huangwc.com/pig/pig-farm-controller/internal/app/controller"
"git.huangwc.com/pig/pig-farm-controller/internal/domain/token"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
"github.com/labstack/echo/v4"
"gorm.io/gorm"
)
// AuthMiddleware 创建一个Echo中间件用于JWT身份验证
// 它依赖于 TokenService 来解析和验证 token并使用 UserRepository 来获取完整的用户信息
func AuthMiddleware(tokenService token.Service, userRepo repository.UserRepository) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
// 从 Authorization header 获取 token
authHeader := c.Request().Header.Get("Authorization")
if authHeader == "" {
return controller.SendErrorWithStatus(c, http.StatusUnauthorized, controller.CodeUnauthorized, "请求未包含授权标头")
}
// 授权标头的格式应为 "Bearer <token>"
parts := strings.Split(authHeader, " ")
if len(parts) != 2 || strings.ToLower(parts[0]) != "bearer" {
return controller.SendErrorWithStatus(c, http.StatusUnauthorized, controller.CodeUnauthorized, "授权标头格式不正确")
}
tokenString := parts[1]
// 解析和验证 token
claims, err := tokenService.ParseToken(tokenString)
if err != nil {
return controller.SendErrorWithStatus(c, http.StatusUnauthorized, controller.CodeUnauthorized, "无效的Token")
}
// 根据 token 中的用户ID从数据库中获取完整的用户信息
user, err := userRepo.FindByID(claims.UserID)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
// Token有效但对应的用户已不存在
return controller.SendErrorWithStatus(c, http.StatusUnauthorized, controller.CodeUnauthorized, "授权用户不存在")
}
// 其他数据库查询错误
return controller.SendErrorWithStatus(c, http.StatusInternalServerError, controller.CodeInternalError, "获取用户信息失败")
}
// 将完整的用户对象存储在 context 中,以便后续的处理函数使用
c.Set(models.ContextUserKey.String(), user)
// 继续处理请求链中的下一个处理程序
return next(c)
}
}
}