| package middleware |
|
|
| import ( |
| "crypto/sha256" |
| "encoding/base64" |
| "encoding/json" |
| "genspark2api/common/config" |
| "net/http" |
| "strings" |
| "time" |
|
|
| "github.com/gin-gonic/gin" |
| ) |
|
|
| |
| type JWTClaims struct { |
| Username string `json:"username"` |
| Exp int64 `json:"exp"` |
| Iat int64 `json:"iat"` |
| Iss string `json:"iss"` |
| } |
|
|
| |
| 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 |
| } |
|
|
| |
| func AuthAdminMiddleware() gin.HandlerFunc { |
| return func(c *gin.Context) { |
| |
| 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 |
| } |
|
|
| |
| authHeader := c.GetHeader("Authorization") |
| if authHeader == "" { |
| |
| token, err := c.Cookie("auth_token") |
| if err != nil { |
| |
| token = c.Query("token") |
| if token == "" { |
| |
| 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 |
| } |
| } |
|
|
| |
| parts := strings.SplitN(authHeader, " ", 2) |
| if !(len(parts) == 2 && parts[0] == "Bearer") { |
| c.JSON(http.StatusUnauthorized, gin.H{ |
| "success": false, |
| "message": "授权格式无效", |
| }) |
| c.Abort() |
| return |
| } |
|
|
| |
| 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() |
| } |
| } |
|
|