mirror of
https://github.com/Direct-Dev-Ru/go-lcg.git
synced 2025-11-15 17:20:00 +00:00
113 lines
3.5 KiB
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)
|
|
}
|