genspark / middleware /auth_admin.go
timigogo's picture
Upload 63 files
fe3856c verified
package middleware
import (
"crypto/sha256"
"encoding/base64"
"encoding/json"
"genspark2api/common/config"
"net/http"
"strings"
"time"
"github.com/gin-gonic/gin"
)
// JWT声明结构
type JWTClaims struct {
Username string `json:"username"`
Exp int64 `json:"exp"`
Iat int64 `json:"iat"`
Iss string `json:"iss"`
}
// 验证JWT令牌
func verifyToken(tokenString string) (*JWTClaims, bool) {
// 分割令牌
parts := strings.Split(tokenString, ".")
if len(parts) != 3 {
return nil, false
}
// 解码头部和载荷
payload, err := base64.RawURLEncoding.DecodeString(parts[1])
if err != nil {
return nil, false
}
// 解析载荷
var claims JWTClaims
if err := json.Unmarshal(payload, &claims); err != nil {
return nil, false
}
// 检查过期时间
if time.Now().Unix() > claims.Exp {
return nil, false
}
// 验证签名
signatureInput := parts[0] + "." + parts[1]
h := sha256.New()
h.Write([]byte(signatureInput + config.ApiSecret))
expectedSignature := base64.RawURLEncoding.EncodeToString(h.Sum(nil))
if parts[2] != expectedSignature {
return nil, false
}
return &claims, true
}
// AuthAdminMiddleware 管理员验证中间件
func AuthAdminMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// 登录页面和登录API不需要认证
if c.Request.URL.Path == "/login" || c.Request.URL.Path == "/admin/login" {
c.Next()
return
}
// 检查是否是静态资源请求
if strings.HasPrefix(c.Request.URL.Path, "/public/") {
c.Next()
return
}
// 从请求头获取token
authHeader := c.GetHeader("Authorization")
if authHeader == "" {
// 尝试从cookie获取token
token, err := c.Cookie("auth_token")
if err != nil {
// 尝试从请求参数获取token
token = c.Query("token")
if token == "" {
// 如果是API请求,返回JSON错误
if strings.HasPrefix(c.Request.URL.Path, "/admin/") &&
c.Request.URL.Path != "/admin/login" {
c.JSON(http.StatusUnauthorized, gin.H{
"success": false,
"message": "请登录后再访问",
})
c.Abort()
return
}
// 如果是普通页面请求,重定向到登录页
c.Redirect(http.StatusFound, "/login")
c.Abort()
return
}
authHeader = "Bearer " + token
} else {
authHeader = "Bearer " + token
}
}
// 检查Authorization格式
parts := strings.SplitN(authHeader, " ", 2)
if !(len(parts) == 2 && parts[0] == "Bearer") {
c.JSON(http.StatusUnauthorized, gin.H{
"success": false,
"message": "授权格式无效",
})
c.Abort()
return
}
// 验证token
claims, valid := verifyToken(parts[1])
if !valid {
if strings.HasPrefix(c.Request.URL.Path, "/admin/") {
c.JSON(http.StatusUnauthorized, gin.H{
"success": false,
"message": "无效的登录凭证",
})
} else {
c.Redirect(http.StatusFound, "/login")
}
c.Abort()
return
}
// 保存用户信息到上下文
c.Set("username", claims.Username)
c.Next()
}
}