TanStack Router предоставляет мощный и гибкий механизм управления состоянием маршрутизации в приложениях на JavaScript, включая работу с контекстами, необходимыми для реализации аутентификации и авторизации пользователей. Контекст аутентификации позволяет централизованно хранить информацию о текущем пользователе, его правах доступа и состоянии сессии, а также интегрировать эти данные с логикой маршрутизации.
Для начала необходимо создать контекст с помощью стандартного API React:
import { createContext, useContext, useState } from 'react';
const AuthContext = createContext(null);
export const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
const login = async (credentials) => {
// Здесь реализуется логика аутентификации
const authenticatedUser = await fakeAuth(credentials);
setUser(authenticatedUser);
};
const logout = () => {
setUser(null);
};
return (
<AuthContext.Provider value={{ user, login, logout }}>
{children}
</AuthContext.Provider>
);
};
export const useAuth = () => useContext(AuthContext);
Ключевые моменты:
AuthContext хранит состояние текущего
пользователя.login и logout предоставляют методы
управления сессией.useAuth является кастомным хуком для доступа к
контексту в любом компоненте.TanStack Router поддерживает использование loader-функций и хуков для проверки состояния аутентификации перед рендерингом маршрутов. Например:
import { createRouter, RouterProvider, route } from '@tanstack/router';
import { useAuth } from './AuthContext';
const Home = () => <div>Главная страница</div>;
const Dashboard = () => <div>Панель пользователя</div>;
const Login = () => <div>Страница входа</div>;
const requireAuth = async ({ context }) => {
const { user } = context.auth;
if (!user) {
throw redirect('/login');
}
return user;
};
const router = createRouter({
context: {
auth: useAuth()
},
routes: [
route({ path: '/', component: Home }),
route({
path: '/dashboard',
component: Dashboard,
loader: requireAuth
}),
route({ path: '/login', component: Login })
]
});
export const App = () => (
<AuthProvider>
<RouterProvider router={router} />
</AuthProvider>
);
Особенности реализации:
context.requireAuth проверяет наличие
пользователя и при отсутствии выполняет редирект.TanStack Router поддерживает реактивное обновление маршрутов при изменении контекста. Это позволяет автоматически перенаправлять пользователя при изменении состояния сессии:
import { useEffect } from 'react';
import { useRouter } from '@tanstack/router';
import { useAuth } from './AuthContext';
const AuthListener = () => {
const router = useRouter();
const { user } = useAuth();
useEffect(() => {
if (!user) {
router.navigate('/login');
} else {
router.navigate('/dashboard');
}
}, [user, router]);
return null;
};
Здесь важно:
useEffect следит за состоянием пользователя и
перенаправляет при изменении.Контекст аутентификации можно расширять для поддержки ролей и прав доступа:
const requireRole = (role) => async ({ context }) => {
const { user } = context.auth;
if (!user || user.role !== role) {
throw redirect('/login');
}
return user;
};
route({
path: '/admin',
component: AdminPanel,
loader: requireRole('admin')
});
requireRole создает loader, проверяющий роль
пользователя перед доступом к маршруту.Для длительных сессий и сохранения состояния между обновлениями страницы можно интегрировать локальное хранилище:
useEffect(() => {
const storedUser = localStorage.getItem('user');
if (storedUser) {
setUser(JSON.parse(storedUser));
}
}, []);
useEffect(() => {
if (user) {
localStorage.setItem('user', JSON.stringify(user));
} else {
localStorage.removeItem('user');
}
}, [user]);
Контекст аутентификации в TanStack Router обеспечивает не только централизованное управление пользователями, но и тесную интеграцию с маршрутизатором, что упрощает реализацию защищенных маршрутов, управление ролями и динамическое перенаправление в приложении на React.