/
varsl
/
HTML-CSS
Обзор
Документация
Войти
/
varsl
/
HTML-CSS
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
frontend/js/auth-manager.js
230 строк
8 KB
varsl
Добавление JavaScript логики
21 дек 2025, 23:16
21 дек 2025, 23:16
9dd2130
Код
Авторство
О чём код?
// js/auth-manager.js - Общий менеджер аутентификации для всех страниц class AuthManager { constructor() { this.apiBaseUrl = 'http://localhost:3000/api'; this.currentUser = null; this.token = localStorage.getItem('token'); this.init(); } init() { this.checkAuthState(); this.setupNavigation(); this.updateAuthButtons(); // Делаем глобально доступным window.authManager = this; } async checkAuthState() { // Если есть токен, проверяем его валидность if (this.token) { try { const user = await this.getCurrentUser(); if (user) { this.currentUser = user; console.log('Пользователь авторизован:', user.email); } else { this.logout(); } } catch (error) { console.error('Ошибка проверки авторизации:', error); this.logout(); } } } async getCurrentUser() { if (!this.token) return null; try { const response = await fetch(`${this.apiBaseUrl}/auth/me`, { headers: { 'Authorization': `Bearer ${this.token}` } }); if (!response.ok) { if (response.status === 401) { // Токен невалиден this.clearAuthData(); return null; } throw new Error('Ошибка получения данных пользователя'); } const data = await response.json(); return data.success ? data.user : null; } catch (error) { console.error('Ошибка получения пользователя:', error); return null; } } updateAuthButtons() { const authButtons = document.querySelector('.auth-buttons'); if (!authButtons) return; if (this.currentUser) { authButtons.innerHTML = ` <div class="dropdown"> <button class="btn btn-primary dropdown-toggle" type="button" id="userDropdown" data-bs-toggle="dropdown"> <i class="fas fa-user"></i> ${this.currentUser.name || 'Профиль'} </button> <ul class="dropdown-menu" aria-labelledby="userDropdown"> <li><a class="dropdown-item" href="dashboard.html"><i class="fas fa-tachometer-alt"></i> Личный кабинет</a></li> <li><a class="dropdown-item" href="profile.html"><i class="fas fa-user"></i> Профиль</a></li> <li><hr class="dropdown-divider"></li> <li><a class="dropdown-item logout-link" href="#"><i class="fas fa-sign-out-alt"></i> Выйти</a></li> </ul> </div> `; // Добавляем обработчик для выхода const logoutLink = document.querySelector('.logout-link'); if (logoutLink) { logoutLink.addEventListener('click', (e) => { e.preventDefault(); this.logout(); }); } } else { authButtons.innerHTML = ` <a href="login.html" class="btn btn-outline">Вход</a> <a href="register.html" class="btn btn-primary">Регистрация</a> `; } } setupNavigation() { // Защита страниц, требующих авторизации const protectedPages = ['dashboard.html', 'profile.html', 'ticket.html', 'excursion.html']; const currentPage = window.location.pathname.split('/').pop(); if (protectedPages.includes(currentPage)) { this.requireAuth(); } // Добавляем токен ко всем запросам если пользователь авторизован this.interceptFetch(); } requireAuth() { if (!this.token || !this.currentUser) { window.location.href = 'login.html'; } } interceptFetch() { const originalFetch = window.fetch; window.fetch = async function(...args) { const [url, options = {}] = args; // Если это запрос к нашему API и пользователь авторизован if (typeof url === 'string' && url.includes('/api/') && window.authManager?.token) { const newOptions = { ...options, headers: { ...options.headers, 'Authorization': `Bearer ${window.authManager.token}` } }; return originalFetch(url, newOptions); } return originalFetch(...args); }; } async login(email, password) { try { const response = await fetch(`${this.apiBaseUrl}/auth/login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, password }) }); const data = await response.json(); if (data.success) { this.token = data.token; this.currentUser = data.user; // Сохраняем в localStorage localStorage.setItem('token', this.token); localStorage.setItem('user', JSON.stringify(this.currentUser)); this.updateAuthButtons(); return { success: true, user: data.user }; } else { return { success: false, message: data.message }; } } catch (error) { console.error('Ошибка входа:', error); return { success: false, message: 'Ошибка соединения с сервером' }; } } async register(userData) { try { const response = await fetch(`${this.apiBaseUrl}/auth/register`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(userData) }); const data = await response.json(); if (data.success) { this.token = data.token; this.currentUser = data.user; localStorage.setItem('token', this.token); localStorage.setItem('user', JSON.stringify(this.currentUser)); this.updateAuthButtons(); return { success: true, user: data.user }; } else { return { success: false, message: data.message, errors: data.errors }; } } catch (error) { console.error('Ошибка регистрации:', error); return { success: false, message: 'Ошибка соединения с сервером' }; } } logout() { this.clearAuthData(); window.location.href = 'index.html'; } clearAuthData() { this.token = null; this.currentUser = null; localStorage.removeItem('token'); localStorage.removeItem('user'); this.updateAuthButtons(); } isAuthenticated() { return !!this.token && !!this.currentUser; } getToken() { return this.token; } getUser() { return this.currentUser; } } // Инициализация при загрузке страницы document.addEventListener('DOMContentLoaded', function() { const authManager = new AuthManager(); });