feat: 认证简化为固定进入密钥 + 页面增强(API 文档/主题切换/版权署名)

- 移除管理员初始化/登录/JWT 流程,改为固定进入密钥(19735500),
  首次启动自动初始化到数据库 settings 表(可改库更新)
- analyze 接口支持可选密钥鉴权:X-Access-Key 请求头或 access_key 字段,
  带密钥强制校验(错误 401),不带密钥保持免鉴权
- 解锁后顶栏"复制 API 文档"按钮:以当前访问 URL 为基础地址动态生成
  Markdown 文档(免鉴权/带密钥两种 curl 示例,供智能体直接调用)
- 白昼/黑夜主题切换:CSS 变量驱动,localStorage 持久化,默认跟随系统
- 修复 hidden 属性被 display:flex 覆盖导致解锁层无法隐藏的问题
- 页面去除"免费/Agnes"文案,页脚署名青梧映星软件开发工作室
- build.bat/build.sh 简化为 Linux 交叉编译(CGO_ENABLED=0)
- 依赖精简:移除 golang-jwt/bcrypt,直接依赖仅 gin/sqlite/gorm/yaml

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-08-13 01:21:18 +08:00
parent a3bbf33358
commit f9cdeb5d64
20 changed files with 341 additions and 465 deletions

View File

@@ -3,12 +3,10 @@ package middleware
import (
"math"
"net/http"
"strings"
"sync"
"time"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v5"
"vision-tool/internal/model"
)
@@ -27,44 +25,6 @@ func CORS() gin.HandlerFunc {
}
}
// ============================================================================
// JWT 鉴权
// ============================================================================
// Claims JWT 载荷。
type Claims struct {
UserID uint `json:"uid"`
Username string `json:"username"`
Role string `json:"role"`
jwt.RegisteredClaims
}
// JWTAuth 校验 Authorization: Bearer <token>,通过后将用户信息写入 context。
func JWTAuth(secret string) gin.HandlerFunc {
return func(c *gin.Context) {
header := c.GetHeader("Authorization")
tokenStr, ok := strings.CutPrefix(header, "Bearer ")
if !ok || tokenStr == "" {
c.AbortWithStatusJSON(http.StatusUnauthorized, model.Err(model.CodeUnauthorized, "未登录"))
return
}
claims := &Claims{}
token, err := jwt.ParseWithClaims(tokenStr, claims, func(t *jwt.Token) (interface{}, error) {
return []byte(secret), nil
})
if err != nil || !token.Valid {
c.AbortWithStatusJSON(http.StatusUnauthorized, model.Err(model.CodeUnauthorized, "登录已过期,请重新登录"))
return
}
c.Set("user_id", claims.UserID)
c.Set("username", claims.Username)
c.Set("role", claims.Role)
c.Next()
}
}
// ============================================================================
// 内存令牌桶限流(全局限流,防匿名刷接口)
// ============================================================================