Files
go-lcg/serve/middleware.go

115 lines
3.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package serve
import (
"net/http"
"strings"
"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 логина из проверки (с учетом BasePath)
if r.URL.Path == makePath("/login") || r.URL.Path == makePath("/api/login") || r.URL.Path == makePath("/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
}
// Для веб-запросов перенаправляем на страницу входа (с учетом BasePath)
http.Redirect(w, r, makePath("/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 (с учетом BasePath)
if r.URL.Path == makePath("/api/login") || r.URL.Path == makePath("/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
apiPrefix := makePath("/api")
return strings.HasPrefix(path, apiPrefix)
}
// RequireAuth обертка для requireAuth из auth.go
func RequireAuth(next http.HandlerFunc) http.HandlerFunc {
return requireAuth(next)
}