Авторизация — это процесс проверки прав пользователя на доступ к определенным ресурсам или функциям приложения. В отличие от аутентификации (кто вы?), авторизация отвечает на вопрос "что вам разрешено?".
Наиболее распространенный подход, где права определяются ролями пользователей.
// Контекст авторизации
const AuthContext = createContext();
export const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
// Проверка роли
const hasRole = (requiredRole) => {
return user?.roles?.includes(requiredRole);
};
// Проверка разрешения
const hasPermission = (requiredPermission) => {
return user?.permissions?.includes(requiredPermission);
};
return (
<AuthContext.Provider value={{ user, setUser, hasRole, hasPermission }}>
{children}
</AuthContext.Provider>
);
};
Создаем компоненты-обертки для контроля доступа:
// Для ролей
const WithRole = ({ role, children }) => {
const { hasRole } = useAuth();
return hasRole(role) ? children : null;
};
// Для разрешений
const WithPermission = ({ permission, children }) => {
const { hasPermission } = useAuth();
return hasPermission(permission) ? children : null;
};
// Использование
<WithRole role="admin">
<AdminPanel />
</WithRole>
Интеграция с React Router:
const RoleRoute = ({ roles, element }) => {
const { hasRole } = useAuth();
const location = useLocation();
const hasAccess = roles.some(role => hasRole(role));
return hasAccess ? (
element
) : (
<Navigate to="/unauthorized" state={{ from: location }} replace />
);
};
// В конфигурации роутера
<Route
path="/admin"
element={<RoleRoute roles={['admin', 'superadmin']} element={<AdminPage />} />}
/>
Динамическое управление доступом:
const FeatureToggle = ({ feature, children }) => {
const { user } = useAuth();
const isEnabled = user?.features?.[feature];
return isEnabled ? children : null;
};
// Использование
<FeatureToggle feature="newDashboard">
<NewDashboard />
</FeatureToggle>
Авторизация на основе атрибутов:
const checkAccess = (resource, action) => {
const { user } = useAuth();
// Проверка сложных правил на основе атрибутов
return user.department === resource.department &&
user.clearanceLevel >= resource.requiredClearance;
};
Получение прав с сервера:
async function loadUserPolicies() {
const response = await fetch('/api/user/policies');
const policies = await response.json();
// Кеширование политик в контексте/сторе
}
api.interceptors.response.use(
response => response,
error => {
if (error.response.status === 403) {
// Показать уведомление о недостатке прав
showForbiddenNotification();
}
return Promise.reject(error);
}
);
CASL: Библиотека для декларативной авторизации
import { AbilityBuilder, createAliasResolver } from '@casl/ability';
function defineAbilitiesFor(user) {
const { can, cannot, build } = new AbilityBuilder();
if (user.role === 'admin') {
can('manage', 'all');
} else {
can('read', 'Article');
can('update', 'Article', { authorId: user.id });
}
return build();
}
React-Admin: Готовые решения для админ-панелей
Auth0/Permissions: Управление правами через Auth0
реализация авторизации в React требует четкой стратегии (RBAC, ABAC, Feature Flags) и должна быть тесно интегрирована как с фронтенд-логикой, так и с бэкенд-системой. Всегда проверяйте права на сервере и используйте принцип минимальных привилегий. Для сложных систем рассмотрите специализированные библиотеки типа CASL.