### 🍪 CRITICAL Cross-Origin Auth - **🔧 SESSION_COOKIE_DOMAIN**: Добавлена поддержка поддоменов `.discours.io` для cross-origin cookies - **🌐 Cross-Origin SSE**: Исправлена работа Server-Sent Events с httpOnly cookies между поддоменами - **🔐 Unified Auth**: Унифицированы настройки cookies для OAuth, login, refresh, logout операций - **📝 MyPy Compliance**: Исправлена типизация `SESSION_COOKIE_SAMESITE` с использованием `cast()` ### 🛠️ Technical Changes - **settings.py**: Добавлен `SESSION_COOKIE_DOMAIN` с типобезопасной настройкой SameSite - **auth/oauth.py**: Обновлены все `set_cookie` вызовы с `domain` параметром - **auth/middleware.py**: Добавлена поддержка `SESSION_COOKIE_DOMAIN` в logout операциях - **resolvers/auth.py**: Унифицированы cookie настройки в login/refresh/logout resolvers - **auth/__init__.py**: Обновлены cookie операции с domain поддержкой ### 📚 Documentation - **docs/auth/sse-httponly-integration.md**: Новая документация по SSE + httpOnly cookies интеграции - **docs/auth/architecture.md**: Обновлены диаграммы для unified httpOnly cookie архитектуры ### 🎯 Impact - ✅ **GraphQL API** (`v3.discours.io`) теперь работает с httpOnly cookies cross-origin - ✅ **SSE сервер** (`connect.discours.io`) работает с теми же cookies - ✅ **Безопасность**: httpOnly cookies защищают от XSS атак - ✅ **UX**: Автоматическая аутентификация без управления токенами в JavaScript
This commit is contained in:
@@ -76,17 +76,33 @@ export const AuthProvider: Component<AuthProviderProps> = (props) => {
|
||||
// Инициализация авторизации при монтировании
|
||||
onMount(async () => {
|
||||
console.log('[AuthProvider] Performing auth initialization...')
|
||||
console.log('[AuthProvider] Checking localStorage token:', !!localStorage.getItem(AUTH_TOKEN_KEY))
|
||||
console.log('[AuthProvider] Checking cookie token:', !!getAuthTokenFromCookie())
|
||||
console.log('[AuthProvider] Checking CSRF token:', !!getCsrfTokenFromCookie())
|
||||
|
||||
// Небольшая задержка для завершения других инициализаций
|
||||
await new Promise((resolve) => setTimeout(resolve, 100))
|
||||
|
||||
// Проверяем текущее состояние авторизации
|
||||
const authStatus = checkAuthStatus()
|
||||
console.log('[AuthProvider] Final auth status after check:', authStatus)
|
||||
setIsAuthenticated(authStatus)
|
||||
|
||||
// 🍪 Для httpOnly cookies проверяем авторизацию через GraphQL запрос
|
||||
try {
|
||||
console.log('[AuthProvider] Checking authentication via GraphQL...')
|
||||
|
||||
// Делаем тестовый запрос для проверки авторизации
|
||||
const result = await query<{ me: { id: string } | null }>(`${location.origin}/graphql`, `
|
||||
query CheckAuth {
|
||||
me {
|
||||
id
|
||||
name
|
||||
email
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
if (result?.me?.id) {
|
||||
console.log('[AuthProvider] User authenticated via httpOnly cookie:', result.me.id)
|
||||
setIsAuthenticated(true)
|
||||
} else {
|
||||
console.log('[AuthProvider] No authenticated user found')
|
||||
setIsAuthenticated(false)
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('[AuthProvider] Authentication check failed:', error)
|
||||
setIsAuthenticated(false)
|
||||
}
|
||||
|
||||
console.log('[AuthProvider] Auth initialization complete, ready for requests')
|
||||
setIsReady(true)
|
||||
@@ -104,9 +120,8 @@ export const AuthProvider: Component<AuthProviderProps> = (props) => {
|
||||
|
||||
if (result?.login?.success) {
|
||||
console.log('[AuthProvider] Login successful')
|
||||
if (result.login.token) {
|
||||
saveAuthToken(result.login.token)
|
||||
}
|
||||
// Backend автоматически установил session_token cookie при успешном login
|
||||
console.log('[AuthProvider] Token saved in httpOnly cookie by backend')
|
||||
setIsAuthenticated(true)
|
||||
// Убираем window.location.href - пусть роутер сам обрабатывает навигацию
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user