This commit is contained in:
@@ -76,13 +76,19 @@ export const AuthProvider: Component<AuthProviderProps> = (props) => {
|
||||
// Инициализация авторизации при монтировании
|
||||
onMount(async () => {
|
||||
console.log('[AuthProvider] Performing auth initialization...')
|
||||
|
||||
|
||||
// 🍪 Для httpOnly cookies проверяем авторизацию через GraphQL запрос
|
||||
try {
|
||||
console.log('[AuthProvider] Checking authentication via GraphQL...')
|
||||
|
||||
// Делаем тестовый запрос для проверки авторизации
|
||||
const result = await query<{ me: { id: string } | null }>(`${location.origin}/graphql`, `
|
||||
|
||||
// Добавляем таймаут для запроса
|
||||
const timeoutPromise = new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error('Auth check timeout')), 10000)
|
||||
)
|
||||
|
||||
const authPromise = query<{ me: { id: string } | null }>(
|
||||
`${location.origin}/graphql`,
|
||||
`
|
||||
query CheckAuth {
|
||||
me {
|
||||
id
|
||||
@@ -90,8 +96,14 @@ export const AuthProvider: Component<AuthProviderProps> = (props) => {
|
||||
email
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
`
|
||||
)
|
||||
|
||||
// Делаем тестовый запрос для проверки авторизации с таймаутом
|
||||
const result = (await Promise.race([authPromise, timeoutPromise])) as {
|
||||
me: { id: string; name: string; email: string } | null
|
||||
}
|
||||
|
||||
if (result?.me?.id) {
|
||||
console.log('[AuthProvider] User authenticated via httpOnly cookie:', result.me.id)
|
||||
setIsAuthenticated(true)
|
||||
@@ -102,10 +114,11 @@ export const AuthProvider: Component<AuthProviderProps> = (props) => {
|
||||
} catch (error) {
|
||||
console.log('[AuthProvider] Authentication check failed:', error)
|
||||
setIsAuthenticated(false)
|
||||
} finally {
|
||||
// Всегда устанавливаем ready в true, даже при ошибке
|
||||
console.log('[AuthProvider] Auth initialization complete, ready for requests')
|
||||
setIsReady(true)
|
||||
}
|
||||
|
||||
console.log('[AuthProvider] Auth initialization complete, ready for requests')
|
||||
setIsReady(true)
|
||||
})
|
||||
|
||||
const login = async (username: string, password: string) => {
|
||||
|
||||
@@ -177,6 +177,81 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
/* Auth Error Screen */
|
||||
.auth-error-screen {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
background-color: var(--background-color);
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.auth-error-content {
|
||||
text-align: center;
|
||||
max-width: 500px;
|
||||
padding: 2rem;
|
||||
background-color: var(--card-background);
|
||||
border-radius: var(--border-radius);
|
||||
border: 1px solid var(--border-color);
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.auth-error-content h2 {
|
||||
color: var(--danger-color);
|
||||
font-size: var(--font-size-xl);
|
||||
margin-bottom: 1rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.auth-error-content p {
|
||||
color: var(--text-color-light);
|
||||
font-size: var(--font-size-base);
|
||||
margin-bottom: 2rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.auth-error-actions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.auth-error-actions .btn {
|
||||
padding: 0.75rem 1.5rem;
|
||||
border-radius: var(--border-radius);
|
||||
border: none;
|
||||
font-size: var(--font-size-base);
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.auth-error-actions .btn-primary {
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.auth-error-actions .btn-primary:hover {
|
||||
background-color: var(--primary-color-dark);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.auth-error-actions .btn-secondary {
|
||||
background-color: transparent;
|
||||
color: var(--text-color-light);
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.auth-error-actions .btn-secondary:hover {
|
||||
background-color: var(--hover-color);
|
||||
border-color: var(--primary-color);
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.error-message {
|
||||
background-color: var(--danger-light);
|
||||
border-left: 4px solid var(--danger-color);
|
||||
|
||||
@@ -29,9 +29,19 @@ export const ProtectedRoute = () => {
|
||||
<Show
|
||||
when={auth.isAuthenticated()}
|
||||
fallback={
|
||||
<div class="loading-screen">
|
||||
<div class="loading-spinner" />
|
||||
<div>Перенаправление на страницу входа...</div>
|
||||
<div class="auth-error-screen">
|
||||
<div class="auth-error-content">
|
||||
<h2>Доступ запрещен</h2>
|
||||
<p>У вас нет прав доступа к админ-панели или ваша сессия истекла.</p>
|
||||
<div class="auth-error-actions">
|
||||
<button class="btn btn-primary" onClick={() => (window.location.href = '/login')}>
|
||||
Войти в аккаунт
|
||||
</button>
|
||||
<button class="btn btn-secondary" onClick={() => auth.logout()}>
|
||||
Выйти из текущего аккаунта
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
*/
|
||||
|
||||
// Экспортируем константы для использования в других модулях
|
||||
export const AUTH_TOKEN_KEY = 'auth_token' // localStorage fallback
|
||||
export const SESSION_COOKIE_NAME = 'session_token' // ✅ httpOnly cookie от backend
|
||||
export const AUTH_TOKEN_KEY = 'auth_token' // localStorage fallback
|
||||
export const SESSION_COOKIE_NAME = 'session_token' // ✅ httpOnly cookie от backend
|
||||
export const CSRF_TOKEN_KEY = 'csrf_token'
|
||||
|
||||
/**
|
||||
@@ -99,6 +99,6 @@ export function checkAuthStatus(): boolean {
|
||||
// Реальная проверка авторизации произойдет при первом GraphQL запросе
|
||||
// Если cookie недействителен, backend вернет ошибку авторизации
|
||||
console.log('[Auth] Using httpOnly cookie authentication - status will be verified by backend')
|
||||
|
||||
return true // ✅ Полагаемся на httpOnly cookie + backend проверку
|
||||
|
||||
return true // ✅ Полагаемся на httpOnly cookie + backend проверку
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user