Files
go-lcg/serve/middleware.go

113 lines
3.5 KiB
Go

package serve
import (
"net/http"
"github.com/direct-dev-ru/linux-command-gpt/config"
)
// AuthMiddleware проверяет аутентификацию для всех запросов
func AuthMiddleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// Проверяем, требуется ли аутентификация
if !config.AppConfig.Server.RequireAuth {
next(w, r)
return
}
// Исключаем страницу входа и API логина из проверки
if r.URL.Path == "/login" || r.URL.Path == "/api/login" || r.URL.Path == "/api/validate-token" {
next(w, r)
return
}
// Проверяем аутентификацию
if !isAuthenticated(r) {
// Для API запросов возвращаем JSON ошибку
if isAPIRequest(r) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte(`{"success": false, "error": "Authentication required"}`))
return
}
// Для веб-запросов перенаправляем на страницу входа
http.Redirect(w, r, "/login", http.StatusSeeOther)
return
}
// Пользователь аутентифицирован, продолжаем
next(w, r)
}
}
// CSRFMiddleware проверяет CSRF токены для POST/PUT/DELETE запросов
func CSRFMiddleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// Проверяем только изменяющие запросы
if r.Method == "GET" || r.Method == "HEAD" || r.Method == "OPTIONS" {
next(w, r)
return
}
// Исключаем некоторые API endpoints
if r.URL.Path == "/api/login" || r.URL.Path == "/api/logout" {
next(w, r)
return
}
// Получаем CSRF токен из заголовка или формы
csrfToken := r.Header.Get("X-CSRF-Token")
if csrfToken == "" {
csrfToken = r.FormValue("csrf_token")
}
if csrfToken == "" {
// Для API запросов возвращаем JSON ошибку
if isAPIRequest(r) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusForbidden)
w.Write([]byte(`{"success": false, "error": "CSRF token required"}`))
return
}
// Для веб-запросов возвращаем ошибку
http.Error(w, "CSRF token required", http.StatusForbidden)
return
}
// Получаем сессионный ID
sessionID := getSessionID(r)
// Проверяем CSRF токен
csrfManager := GetCSRFManager()
if csrfManager == nil || !csrfManager.ValidateToken(csrfToken, sessionID) {
// Для API запросов возвращаем JSON ошибку
if isAPIRequest(r) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusForbidden)
w.Write([]byte(`{"success": false, "error": "Invalid CSRF token"}`))
return
}
// Для веб-запросов возвращаем ошибку
http.Error(w, "Invalid CSRF token", http.StatusForbidden)
return
}
// CSRF токен валиден, продолжаем
next(w, r)
}
}
// isAPIRequest проверяет, является ли запрос API запросом
func isAPIRequest(r *http.Request) bool {
path := r.URL.Path
return len(path) >= 4 && path[:4] == "/api"
}
// RequireAuth обертка для requireAuth из auth.go
func RequireAuth(next http.HandlerFunc) http.HandlerFunc {
return requireAuth(next)
}