0d84b07f68
CI / docker (push) Successful in 1m58s
Go + Vue 管理台:Agent 隧道、域名反代、IP 安全、访客验证与监控大盘。 Gitea Actions CI 多架构镜像;纯 Go SQLite、无 CGO Docker 构建。 Co-authored-by: Cursor <cursoragent@cursor.com>
57 lines
1.3 KiB
Go
57 lines
1.3 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/wormhole/wormhole/internal/auth"
|
|
"github.com/wormhole/wormhole/internal/store"
|
|
)
|
|
|
|
func (s *Server) authMiddleware() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
if key := c.GetHeader("X-API-Key"); key != "" {
|
|
user, err := s.store.ValidateAPIKey(key)
|
|
if err != nil {
|
|
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "invalid api key"})
|
|
return
|
|
}
|
|
c.Set("claims", &auth.Claims{
|
|
UserID: user.ID,
|
|
Username: user.Username,
|
|
Role: user.Role,
|
|
})
|
|
c.Set("auth_via", "apikey")
|
|
c.Next()
|
|
return
|
|
}
|
|
|
|
token := c.GetHeader("Authorization")
|
|
if len(token) > 7 && token[:7] == "Bearer " {
|
|
token = token[7:]
|
|
} else {
|
|
token = c.Query("token")
|
|
}
|
|
if token == "" {
|
|
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
|
|
return
|
|
}
|
|
claims, err := s.auth.ParseToken(token)
|
|
if err != nil {
|
|
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "invalid token"})
|
|
return
|
|
}
|
|
c.Set("claims", claims)
|
|
c.Set("auth_via", "jwt")
|
|
c.Next()
|
|
}
|
|
}
|
|
|
|
func pageParams(c *gin.Context) store.PageParams {
|
|
return store.ParsePageQuery(
|
|
c.DefaultQuery("page", "1"),
|
|
c.DefaultQuery("page_size", "20"),
|
|
c.Query("q"),
|
|
)
|
|
}
|