Files
zhilv 5414c9c865 feat: 分类/变体体系 + 用户认证 + 管理后台
- 运行时分类体系:Shell/Python/JavaScript/Ruby/PHP 各含变体
- 用户注册/登录(JWT + bcrypt),首个注册用户为管理员
- 管理后台 /admin 动态管理分类和变体
- 脚本市场支持按分类筛选
- CodeMirror 语言模式根据分类名称自动切换
- 结果页展示该分类下所有变体的运行命令
- source 命令变体用于 Shell 类继承环境变量

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 15:02:20 +08:00

54 lines
1.1 KiB
Go

package middleware
import (
"net/http"
"strings"
"github.com/gin-gonic/gin"
"gitea.kmux.cn/zhilv/scriptforge/internal/auth"
)
func JWTAuth(authSvc *auth.AuthService) gin.HandlerFunc {
return func(c *gin.Context) {
tokenStr := ""
// Check Authorization header
authHeader := c.GetHeader("Authorization")
if strings.HasPrefix(authHeader, "Bearer ") {
tokenStr = strings.TrimPrefix(authHeader, "Bearer ")
}
// Also check query param for convenience
if tokenStr == "" {
tokenStr = c.Query("token")
}
if tokenStr == "" {
c.Next() // No token, proceed as anonymous
return
}
claims, err := authSvc.ParseToken(tokenStr)
if err != nil {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "invalid token"})
return
}
c.Set("user_id", claims.UserID)
c.Set("username", claims.Username)
c.Set("role", claims.Role)
c.Next()
}
}
func AdminOnly(authSvc *auth.AuthService) gin.HandlerFunc {
return func(c *gin.Context) {
role, exists := c.Get("role")
if !exists || role != "admin" {
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "admin only"})
return
}
c.Next()
}
}