Найти тему
Хикмет Садигзаде

React Router 6: частные маршруты (Protected Routes)

В React Router частные маршруты (или Protected Routes) требуют, чтобы пользователь был аутентифицирован для доступа к данным маршрутам или страницам. Если пользователь не аутентифицирован для конкретной страницы, у него будет запрещен доступ к ней. Классическим примером является аутентификация в React-приложении, где пользователю разрешен доступ только к защищенным страницам после успешной аутентификации (проверки подлинности). Однако авторизация простирается дальше аутентификации. Например, у пользователя могут быть назначены роли и разрешения, которые определяют его доступ к определенным областям приложения.

Это руководство по использованию частных маршрутов с React Router 6. Здесь вы найдете код, который демонстрирует примеры использования React Router v6.

Начнем с простого проекта на React, в котором используется React Router для навигации пользователя между страницами. В следующем функциональном компоненте мы импортируем компоненты Link и Route из React Router для определения различных маршрутов. У нас также есть индексный маршрут, который загружает компонент Landing, и маршрут без совпадений, который загружает JSX. Оба этих маршрута действуют как запасные варианты:

-2

Следующим шагом нашей задачей является защита всех маршрутов от несанкционированного доступа (за исключением общедоступного маршрута <Landing />). У каждой страницы есть свой механизм проверки доступа. Требования к авторизации для каждой страницы различны, за исключением страницы Home и страницы Dashboard, которые имеют одинаковые требования к авторизации.

-3

В начале мы разработаем механизм входа и выхода пользователя. Мы будем использовать две кнопки, которые будут условно отображаться в зависимости от статуса аутентификации пользователя. Если пользователь аутентифицирован, будет отображаться кнопка выхода из системы. Если пользователь не аутентифицирован, будет отображаться кнопка входа в систему. При обработке событий мы будем использовать хук React useState для установки или сброса значения пользователя на null.

-4

Пользователь может быть либо аутентифицированным (вошедшим в систему), либо неаутентифицированным (вышедшим из системы). Следующим шагом мы собираемся защитить наш первый маршрут. Для этого мы начнем с реализации перенаправления с помощью React Router в нашем домашнем компоненте, где мы уже передали пользователя в качестве props компоненту.

-5

Когда у нас есть аутентифицированный пользователь, компонент Home не выполняет блок условия if-else и отображает свое основное содержимое. Однако, если пользователь не аутентифицирован, компонент Home отображает компонент React Router Redirect, который перенаправляет пользователя на целевую страницу. Если пользователь находится на домашней странице и выходит из системы, нажимая на кнопку, то он будет перенаправлен с защищенной страницы.

Мы успешно защитили наш первый компонент React с помощью React Router. Однако этот подход не является масштабируемым, так как мы должны повторять одну и ту же логику на каждом защищенном маршруте. Кроме того, логика перенаправления не должна быть встроена в компонент Home, а лучше вынести ее наружу. Поэтому мы создадим отдельный компонент, в котором будет содержаться логика защиты.

-6

Затем мы можем использовать новый компонент защищенного маршрута в качестве обертки для компонента Home. Теперь сам компонент Home не нужно знать о механизме защиты, так как это будет управляться нашим новым компонентом защитного маршрута.

-7

Этот новый компонент защитного маршрута служит абстракцией для механизма авторизации, который обеспечивает защиту определенных страниц от несанкционированного доступа. Мы разработали его как повторно используемый компонент, который можно объединить с другими компонентами, и это позволяет нам расширить его реализацию по мере необходимости. Например, в большинстве случаев (например, когда пользователь не проходит аутентификацию) мы хотим перенаправить пользователя на общедоступный маршрут (например, '/landing'). Однако мы также можем указать необязательный путь для перенаправления:

-8

Мы вернемся к расширению этого компонента, когда нам придется иметь дело с разрешениями и ролями. На данный момент мы будем повторно использовать этот компонент для других маршрутов, которым требуется такой же уровень защиты. Например, страница Dashboard также требует, чтобы пользователь был аутентифицирован, поэтому давайте защитим этот маршрут.

-9

Для обеспечения защиты двух однородных маршрутов с одинаковым уровнем авторизации лучшим подходом будет использование компонента Layout Route, который будет отображать компонент ProtectedRoute для обоих вложенных маршрутов. Это позволит нам эффективно управлять авторизацией и защитить оба маршрута одновременно.

-10

Путем замены дочернего компонента Outlet React Router на компонент ProtectedRoute в качестве компонента Layout, мы можем достичь желаемого результат. Однако, если мы попытаемся использовать ProtectedRoute как обертку, как делали ранее, это может привести к неправильной работе нашего приложения. Поэтому, для обеспечения правильного функционирования, мы можем дополнительно отображать дочерние элементы там, где ProtectedRoute не используется в качестве компонента макета. Таким образом, мы можем успешно использовать компонент ProtectedRoute и отображать соответствующие элементы в зависимости от контекста и требований нашего приложения.

-11

Вот и все, что мы нуждались для обеспечения защиты частных маршрутов в основном случае аутентифицированного пользователя. Однако в более сложных приложениях, возможно, вам понадобится работа с разрешениями и ролями. Мы можем моделировать оба случая, предоставив пользователю массивы разрешений и ролей, поскольку может быть несколько прав доступа и ролей. Это позволит нам более детально контролировать доступ пользователей в зависимости от их ролей и разрешений.

-12

В настоящее время компонент ProtectedRoute работает только с аутентифицированными пользователями в процессе авторизации. Однако нам необходимо его расширить, чтобы обрабатывать разрешения и роли. Поэтому мы предоставим разработчикам возможность передавать логическое условие, которое будет действовать как абстрактная защита для рендеринга защищенного компонента. Это позволит нам более гибко контролировать доступ пользователей на основе их разрешений и ролей.

-13

В связи с предыдущими изменениями, мы уже определили условие внутри компонента ProtectedRoute. Однако теперь нам необходимо определить это условие снаружи компонента. Это относится к нашим существующим защищенным маршрутам, а также новым защищенным маршрутам, которые требуют наличия определенных разрешений или роли у пользователя. Мы можем легко настроить эти условия, чтобы дополнительно обеспечить контроль доступа и защитить соответствующие маршруты от несанкционированного доступа.

-14

В то время как страницы Home и Dashboard требуют наличия пользователя (то есть аутентифицированного пользователя), страницы Analytics и Admin требуют прохождения аутентификации пользователя и наличия определенных разрешений или ролей. Вы можете попробовать самостоятельно удалить у пользователя либо его роли, либо разрешения.

Кроме того, защищенный маршрут для страниц аналитики и администрирования использует необязательный параметр redirectPath. Если пользователь не соответствует требованиям авторизации по разрешениям или ролям, он будет перенаправлен на защищенную страницу Home. Если пользователь не прошел аутентификацию, он будет перенаправлен на целевую страницу. Это позволяет осуществить дополнительный контроль доступа и гибко управлять перенаправлениями в зависимости от статуса аутентификации и требований по разрешениям или ролям.

Если вы предпочитаете использовать компоненты высшего порядка, вы также можете создать защищенный маршрут с помощью HoC (Higher-Order Component). В любом случае, я надеюсь, что данное руководство помогло вам понять, как работают частные маршруты (также известные как защищенные маршруты) в React Router и как использовать их для защиты маршрутов, которые требуют авторизации в зависимости от статуса аутентификации пользователя или его ролей и разрешений.