Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Роль пользователя определяется несколькими способами в зависимости от архитектуры приложения: из JWT токена, из API ответа при логине, из контекста приложения или из базы данных.
1. Определение роли из JWT токена
// Декодирование JWT на фронтенде
const decodeToken = (token) => {
try {
const base64Url = token.split('.')[1];
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
const jsonPayload = decodeURIComponent(
atob(base64).split('').map((c) => {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join('')
);
return JSON.parse(jsonPayload);
} catch (err) {
console.error('Invalid token', err);
return null;
}
};
// Получение роли из токена
const getRole = () => {
const token = localStorage.getItem('token');
if (!token) return null;
const payload = decodeToken(token);
return payload?.role; // или payload?.roles (массив ролей)
};
2. Определение роли из контекста приложения
// AuthContext.js
import { createContext, useState, useCallback } from 'react';
export const AuthContext = createContext();
export function AuthProvider({ children }) {
const [user, setUser] = useState(null);
const login = async (email, password) => {
const response = await fetch('/api/v1/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password }),
});
const data = await response.json();
setUser(data.user); // { id, email, role: 'admin' }
localStorage.setItem('token', data.accessToken);
};
const getRole = useCallback(() => {
return user?.role || null;
}, [user]);
return (
<AuthContext.Provider value={{ user, login, getRole }}>
{children}
</AuthContext.Provider>
);
}
// Использование в компоненте
import { useContext } from 'react';
function UserProfile() {
const { user, getRole } = useContext(AuthContext);
const role = getRole();
return (
<div>
<p>Пользователь: {user?.email}</p>
<p>Роль: {role}</p>
</div>
);
}
3. Определение роли из API при логине
// При успешном логине сервер отправляет роль
const handleLogin = async (email, password) => {
const response = await fetch('/api/v1/auth/login', {
method: 'POST',
body: JSON.stringify({ email, password }),
});
const { user, accessToken } = await response.json();
// Роль уже в объекте user
const userRole = user.role; // 'admin', 'user', 'moderator'
// Сохраняем полные данные пользователя
sessionStorage.setItem('user', JSON.stringify(user));
localStorage.setItem('token', accessToken);
};
4. Проверка доступа к защищённым маршрутам
// ProtectedRoute.jsx
import { Navigate } from 'react-router-dom';
import { useContext } from 'react';
import { AuthContext } from './AuthContext';
export function ProtectedRoute({ children, requiredRole }) {
const { user, getRole } = useContext(AuthContext);
const userRole = getRole();
// Если нет авторизации
if (!user) {
return <Navigate to="/login" replace />;
}
// Если требуется определённая роль
if (requiredRole && userRole !== requiredRole) {
return <Navigate to="/forbidden" replace />;
}
return children;
}
// Использование
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/login" element={<Login />} />
<Route
path="/admin"
element={
<ProtectedRoute requiredRole="admin">
<AdminPanel />
</ProtectedRoute>
}
/>
</Routes>
</BrowserRouter>
5. Проверка роли в компонентах
// Условный рендеринг на основе роли
function Dashboard() {
const { user } = useContext(AuthContext);
const isAdmin = user?.role === 'admin';
const isModerator = user?.role === 'moderator';
return (
<div>
{isAdmin && <AdminPanel />}
{isModerator && <ModerationQueue />}
<UserContent />
</div>
);
}
6. Проверка роли при API запросах
// Утилита для добавления токена и роли в заголовки
const fetchWithAuth = async (url, options = {}) => {
const token = localStorage.getItem('token');
const user = JSON.parse(sessionStorage.getItem('user') || '{}');
return fetch(url, {
...options,
headers: {
...options.headers,
'Authorization': `Bearer ${token}`,
'X-User-Role': user.role,
},
});
};
// Использование
const deleteUser = async (userId) => {
const response = await fetchWithAuth(`/api/v1/users/${userId}`, {
method: 'DELETE',
});
return response.json();
};
7. Role-Based Access Control (RBAC)
// Константы ролей
export const ROLES = {
ADMIN: 'admin',
MODERATOR: 'moderator',
USER: 'user',
GUEST: 'guest',
};
// Матрица доступа
const PERMISSIONS = {
[ROLES.ADMIN]: ['read', 'create', 'update', 'delete'],
[ROLES.MODERATOR]: ['read', 'update'],
[ROLES.USER]: ['read'],
[ROLES.GUEST]: [],
};
// Проверка доступа
const hasPermission = (role, action) => {
return PERMISSIONS[role]?.includes(action) ?? false;
};
// Использование
if (hasPermission(user.role, 'delete')) {
// Показываем кнопку удаления
}
Выбор метода зависит от требований безопасности и архитектуры приложения. В production рекомендуется проверять роль как на фронтенде (для UX), так и на бэкенде (для безопасности).