modified: main_dc/yalarba/api_yal/go.mod
modified: main_dc/yalarba/api_yal/go.sum modified: main_dc/yalarba/api_yal/internal/config/config.go modified: main_dc/yalarba/api_yal/internal/router/router.go add stock middleware from chi
This commit is contained in:
@@ -22,6 +22,7 @@ require (
|
|||||||
require (
|
require (
|
||||||
github.com/go-chi/chi v1.5.5
|
github.com/go-chi/chi v1.5.5
|
||||||
github.com/go-chi/chi/v5 v5.2.5
|
github.com/go-chi/chi/v5 v5.2.5
|
||||||
|
github.com/go-chi/cors v1.2.2
|
||||||
github.com/go-playground/validator/v10 v10.30.1
|
github.com/go-playground/validator/v10 v10.30.1
|
||||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
github.com/jinzhu/now v1.1.5 // indirect
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ github.com/go-chi/chi v1.5.5 h1:vOB/HbEMt9QqBqErz07QehcOKHaWFtuj87tTDVz2qXE=
|
|||||||
github.com/go-chi/chi v1.5.5/go.mod h1:C9JqLr3tIYjDOZpzn+BCuxY8z8vmca43EeMgyZt7irw=
|
github.com/go-chi/chi v1.5.5/go.mod h1:C9JqLr3tIYjDOZpzn+BCuxY8z8vmca43EeMgyZt7irw=
|
||||||
github.com/go-chi/chi/v5 v5.2.5 h1:Eg4myHZBjyvJmAFjFvWgrqDTXFyOzjj7YIm3L3mu6Ug=
|
github.com/go-chi/chi/v5 v5.2.5 h1:Eg4myHZBjyvJmAFjFvWgrqDTXFyOzjj7YIm3L3mu6Ug=
|
||||||
github.com/go-chi/chi/v5 v5.2.5/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0=
|
github.com/go-chi/chi/v5 v5.2.5/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0=
|
||||||
|
github.com/go-chi/cors v1.2.2 h1:Jmey33TE+b+rB7fT8MUy1u0I4L+NARQlK6LhzKPSyQE=
|
||||||
|
github.com/go-chi/cors v1.2.2/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
|
||||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||||
|
|||||||
@@ -14,8 +14,16 @@ type Config struct {
|
|||||||
ServerPort string
|
ServerPort string
|
||||||
UploadPath string
|
UploadPath string
|
||||||
LogLevel string
|
LogLevel string
|
||||||
Environment string
|
Environment string `yaml:"environment" env:"ENVIRONMENT" default:"development"`
|
||||||
AppPort string
|
AppPort string
|
||||||
|
CORS struct {
|
||||||
|
AllowedOrigins []string `yaml:"allowed_origins" env:"CORS_ALLOWED_ORIGINS"`
|
||||||
|
} `yaml:"cors"`
|
||||||
|
|
||||||
|
RateLimit struct {
|
||||||
|
Enabled bool `yaml:"enabled" env:"RATE_LIMIT_ENABLED" default:"false"`
|
||||||
|
RequestsPerSecond int `yaml:"requests_per_second" env:"RATE_LIMIT_REQUESTS" default:"100"`
|
||||||
|
} `yaml:"rate_limit"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func Load() *Config {
|
func Load() *Config {
|
||||||
|
|||||||
@@ -3,11 +3,16 @@ package router
|
|||||||
import (
|
import (
|
||||||
"api_yal/internal/config"
|
"api_yal/internal/config"
|
||||||
"api_yal/internal/logger"
|
"api_yal/internal/logger"
|
||||||
|
CastomMiddleware "api_yal/internal/middleware"
|
||||||
|
"time"
|
||||||
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/go-chi/chi/v5"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-chi/chi/v5"
|
||||||
|
ChiMiddleware "github.com/go-chi/chi/v5/middleware"
|
||||||
|
"github.com/go-chi/cors"
|
||||||
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SetupRouter(db *gorm.DB, config *config.Config) http.Handler {
|
func SetupRouter(db *gorm.DB, config *config.Config) http.Handler {
|
||||||
@@ -16,6 +21,9 @@ func SetupRouter(db *gorm.DB, config *config.Config) http.Handler {
|
|||||||
zapLogger.Info("Start setup routers")
|
zapLogger.Info("Start setup routers")
|
||||||
r := chi.NewRouter()
|
r := chi.NewRouter()
|
||||||
|
|
||||||
|
// Добавляем все production middleware
|
||||||
|
addProductionMiddleware(r, config)
|
||||||
|
|
||||||
// Health check
|
// Health check
|
||||||
r.Get("/health", func(w http.ResponseWriter, r *http.Request) {
|
r.Get("/health", func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
@@ -23,7 +31,8 @@ func SetupRouter(db *gorm.DB, config *config.Config) http.Handler {
|
|||||||
json.NewEncoder(w).Encode(map[string]string{"status": "healthy"})
|
json.NewEncoder(w).Encode(map[string]string{"status": "healthy"})
|
||||||
})
|
})
|
||||||
|
|
||||||
r.Group()
|
// Auth middleware
|
||||||
|
r.Use(CastomMiddleware.AuthMiddlewareWithContext)
|
||||||
|
|
||||||
zapLogger.Info("End setup routers")
|
zapLogger.Info("End setup routers")
|
||||||
|
|
||||||
@@ -33,3 +42,67 @@ func SetupRouter(db *gorm.DB, config *config.Config) http.Handler {
|
|||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addProductionMiddleware добавляет все необходимые middleware для production окружения
|
||||||
|
func addProductionMiddleware(r *chi.Mux, config *config.Config) {
|
||||||
|
// Request ID middleware - добавляет уникальный ID к каждому запросу
|
||||||
|
r.Use(ChiMiddleware.RequestID)
|
||||||
|
|
||||||
|
// Real IP middleware - корректно определяет реальный IP клиента (за прокси)
|
||||||
|
r.Use(ChiMiddleware.RealIP)
|
||||||
|
|
||||||
|
// Logger middleware - логирует все запросы в формате Apache
|
||||||
|
r.Use(ChiMiddleware.Logger)
|
||||||
|
|
||||||
|
// Recoverer middleware - восстанавливает после паники и возвращает 500
|
||||||
|
r.Use(ChiMiddleware.Recoverer)
|
||||||
|
|
||||||
|
// Timeout middleware - устанавливает таймаут на запросы (30 секунд)
|
||||||
|
r.Use(ChiMiddleware.Timeout(30 * time.Second))
|
||||||
|
|
||||||
|
// Compress middleware - сжимает ответы (gzip)
|
||||||
|
r.Use(ChiMiddleware.Compress(5, "gzip"))
|
||||||
|
|
||||||
|
// StripSlashes middleware - удаляет слеши в конце URL или редиректит
|
||||||
|
r.Use(ChiMiddleware.StripSlashes)
|
||||||
|
|
||||||
|
// CORS middleware - настройка CORS для production
|
||||||
|
r.Use(cors.Handler(cors.Options{
|
||||||
|
AllowedOrigins: config.CORS.AllowedOrigins,
|
||||||
|
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"},
|
||||||
|
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token", "X-Request-ID"},
|
||||||
|
ExposedHeaders: []string{"Link", "X-Request-ID"},
|
||||||
|
AllowCredentials: true,
|
||||||
|
MaxAge: 300,
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Content-Type middleware - проверяет Content-Type для POST/PUT запросов
|
||||||
|
r.Use(ChiMiddleware.AllowContentType("application/json", "application/xml"))
|
||||||
|
|
||||||
|
// Дополнительные middleware в зависимости от конфигурации
|
||||||
|
if config.Environment == "development" {
|
||||||
|
// Добавляем дополнительное логирование для разработки
|
||||||
|
r.Use(ChiMiddleware.Logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.RateLimit.Enabled {
|
||||||
|
// Добавляем rate limiting если включено в конфиге
|
||||||
|
r.Use(ChiMiddleware.Throttle(config.RateLimit.RequestsPerSecond))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Security headers middleware
|
||||||
|
r.Use(func(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||||
|
w.Header().Set("X-Frame-Options", "DENY")
|
||||||
|
w.Header().Set("X-XSS-Protection", "1; mode=block")
|
||||||
|
w.Header().Set("Referrer-Policy", "strict-origin-when-cross-origin")
|
||||||
|
|
||||||
|
if config.Environment == "production" {
|
||||||
|
w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
|
||||||
|
}
|
||||||
|
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user