first commit
Some checks failed
CI/CD Pipeline / Test (push) Failing after 22m19s
CI/CD Pipeline / Security Scan (push) Failing after 5m57s
CI/CD Pipeline / Build (amd64, darwin) (push) Has been skipped
CI/CD Pipeline / Build (amd64, linux) (push) Has been skipped
CI/CD Pipeline / Build (amd64, windows) (push) Has been skipped
CI/CD Pipeline / Build (arm64, darwin) (push) Has been skipped
CI/CD Pipeline / Build (arm64, linux) (push) Has been skipped
CI/CD Pipeline / Build Docker Image (push) Has been skipped
CI/CD Pipeline / Create Release (push) Has been skipped
Some checks failed
CI/CD Pipeline / Test (push) Failing after 22m19s
CI/CD Pipeline / Security Scan (push) Failing after 5m57s
CI/CD Pipeline / Build (amd64, darwin) (push) Has been skipped
CI/CD Pipeline / Build (amd64, linux) (push) Has been skipped
CI/CD Pipeline / Build (amd64, windows) (push) Has been skipped
CI/CD Pipeline / Build (arm64, darwin) (push) Has been skipped
CI/CD Pipeline / Build (arm64, linux) (push) Has been skipped
CI/CD Pipeline / Build Docker Image (push) Has been skipped
CI/CD Pipeline / Create Release (push) Has been skipped
This commit is contained in:
87
internal/middleware/security.go
Normal file
87
internal/middleware/security.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/subconverter-go/internal/logging"
|
||||
)
|
||||
|
||||
// SetupSecurity 设置安全中间件
|
||||
// 添加各种安全相关的HTTP头
|
||||
func SetupSecurity() fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
// 设置安全相关的HTTP头
|
||||
c.Set("X-Content-Type-Options", "nosniff")
|
||||
c.Set("X-Frame-Options", "DENY")
|
||||
c.Set("X-XSS-Protection", "1; mode=block")
|
||||
c.Set("Referrer-Policy", "strict-origin-when-cross-origin")
|
||||
c.Set("Content-Security-Policy", "default-src 'self'")
|
||||
|
||||
// 移除服务器信息
|
||||
c.Set("Server", "")
|
||||
|
||||
return c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// SetupAuthentication 设置认证中间件
|
||||
// 验证访问令牌,保护API端点
|
||||
func SetupAuthentication(logger *logging.Logger, validTokens []string) fiber.Handler {
|
||||
allowed := make(map[string]struct{}, len(validTokens))
|
||||
for _, token := range validTokens {
|
||||
if token == "" {
|
||||
continue
|
||||
}
|
||||
allowed[strings.TrimSpace(token)] = struct{}{}
|
||||
}
|
||||
|
||||
return func(c *fiber.Ctx) error {
|
||||
// 如果没有配置令牌,跳过认证
|
||||
if len(allowed) == 0 {
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
token := ""
|
||||
|
||||
authHeader := c.Get("Authorization")
|
||||
if strings.HasPrefix(authHeader, "Bearer ") {
|
||||
token = strings.TrimSpace(strings.TrimPrefix(authHeader, "Bearer "))
|
||||
}
|
||||
|
||||
if token == "" {
|
||||
token = strings.TrimSpace(c.Query("token"))
|
||||
}
|
||||
|
||||
if token == "" {
|
||||
logger.Warn("Missing authorization token")
|
||||
return forbiddenResponse(c)
|
||||
}
|
||||
|
||||
if _, ok := allowed[token]; !ok {
|
||||
logger.WithField("token", token).Warn("Invalid authorization token")
|
||||
return forbiddenResponse(c)
|
||||
}
|
||||
|
||||
c.Locals("authenticated", true)
|
||||
c.Locals("token", token)
|
||||
|
||||
return c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func forbiddenResponse(c *fiber.Ctx) error {
|
||||
c.Set("Content-Type", "text/plain")
|
||||
return c.Status(fiber.StatusForbidden).SendString("Forbidden\n")
|
||||
}
|
||||
|
||||
// SetupCompression 设置压缩中间件
|
||||
// 启用响应压缩,减少传输数据量
|
||||
func SetupCompression() fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
// 设置Accept-Encoding头
|
||||
c.Set("Accept-Encoding", "gzip, deflate")
|
||||
|
||||
return c.Next()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user