Как защитить маршруты в Next.js 13 - защита на стороне клиента, на стороне сервера и на основе Middleware

Как защитить маршруты в Next.js 13 - защита на стороне клиента, на стороне сервера и на основе Middleware

Содержание
  1. Введение
  2. Маршрутизация в Next.js
  3. Как создать маршрут в Next.js
  4. Защита маршрутов на стороне клиента
  5. Защита маршрутов на стороне сервера
  6. Защита маршрутов на основе промежуточного ПО
  7. Заключение

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

В этом уроке мы рассмотрим, как защитить маршруты в Next.js 13 с помощью трех различных методов. Мы узнаем, как защитить маршруты на стороне клиента и на стороне сервера, а также с помощью промежуточного ПО.

Введение

Защита маршрутов - важный аспект разработки веб-приложений. Она очень нужна при обработке процесса аутентификации в вашем приложении.

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

Прежде чем мы отправимся в это путешествие, приведем некоторые предварительные условия, чтобы вы получили максимум пользы от этого руководства:

  • Базовое понимание Next.js, Node.js и JavaScript
  • Знакомство с менеджерами пакетов, такими как NPM или Yarn
  • Редактор кода по вашему выбору (например, Visual Studio Code)
  • Node.js и npm (или yarn) установлены на вашей машине.

Давайте вкратце обсудим, что такое Next.js. Согласно официальной [документации] (https://nextjs.org/docs/getting-started/installation), компания Vercel создала Next.js - фреймворк React, используемый в основном для создания полнофункциональных веб-приложений. Next.js предлагает различные возможности, включая маршрутизацию системы на основе файлов, рендеринг как на стороне клиента, так и на стороне сервера, оптимизацию изображений и расширенную поддержку TypeScript.

Чтобы начать создавать веб-приложения с помощью Next.js, вы можете создать новый проект Next.js с помощью следующих команд:

npx create-next-app@latest

После успешной установки вы получите несколько предложений по настройке вашего приложения Next.js. Я рекомендую выбрать маршрутизатор приложений, так как это рекомендуемый выбор для маршрутизации в Next.js 13. В этом руководстве мы будем использовать Tailwind CSS для стилизации и TypeScript.

Маршрутизация в Next.js

В отличие от приложений React, которые часто полагаются на сторонние пакеты вроде react-router-dom для маршрутизации, Next.js 13 имеет свой собственный встроенный маршрутизатор приложений. Этот маршрутизатор поддерживает общие макеты, вложенную маршрутизацию, состояния загрузки, обработку ошибок и многое другое.

Next.js использует файловую систему маршрутизации. Это означает, что папки, содержащие файлы page.js, определяют маршруты. Папка также может содержать одну или несколько вложенных папок.

Next.js упрощает реализацию защищенных маршрутов. Прежде чем перейти к созданию защищенных маршрутов в Next.js, давайте разберемся, как создаются маршруты.

Как создать маршрут в Next.js

Чтобы продемонстрировать различные способы защиты маршрутов в Next.js 13, мы создадим маршруты: Дома, Панели, Админа, Настройки и Профиль.

Давайте выполним некоторую очистку кода. Удалите весь код, находящийся в файле “page.tsx ” папки app, и вставьте следующий код:

// app/page.tsx
<main className="flex h-screen items-center justify-center text-center">Домашняя страница</main>

Файл “page.tsx ” в папке app будет служить домашней страницей для этого руководства. Внутри папки app создайте папку “Profile”, а в ней - файл “page.tsx”. Добавьте в него следующий код:

// profile/page.tsx

<main className="flex h-screen items-center justify-center text-center">
	<div>
		<h1>Страница профиля</h1>
	</div>
</main>

Повторите этот процесс для папок “Dashboard”, “Admin” и “Settings”. Каждая из них должна содержать файл “page.tsx”. Если вы выполнили эти действия, значит, вы успешно настроили свои маршруты.

Как уже говорилось ранее, мы обсудим различные способы защиты маршрутов.

Защита маршрутов на стороне клиента

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

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

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

Чтобы упростить аутентификацию, создайте файл “Auth.ts” в папке Utils, которая должна находиться в корне приложения Next.js. Файл должен содержать следующий код:

export const isAuthenticated = false;

Чтобы защитить маршрут Profile внутри клиентского компонента, мы будем использовать useLayoutEffect. Давайте посмотрим, как это работает, рассмотрев приведенный ниже код:

// profile/page.tsx

'use client';
import { isAuthenticated } from '@/Utils/Auth';
import { redirect } from 'next/navigation';
import { useLayoutEffect } from 'react';

const Profile = () => {
	useLayoutEffect(() => {
		const isAuth = isAuthenticated;
		if (!isAuth) {
			redirect('/');
		}
	}, []);

	return (
		<main className="flex h-screen items-center justify-center text-center">
			<div>
				<h1>Профиль</h1>
			</div>
		</main>
	);
};

export default Profile;

В этом примере кода мы продемонстрировали простой, но эффективный метод защиты маршрутов в клиентском компоненте.

Объединив хук useLayoutEffect с проверкой аутентификации и функцией redirect, мы создали базовый механизм защиты маршрутов. Неавторизованные пользователи перенаправляются с защищенного маршрута на маршрут “Home”, что повышает безопасность вашего приложения.

Внутри компонента Profile мы используем хук useLayoutEffect для проверки статуса аутентификации пользователя при установке компонента. Мы вызываем функцию isAuthenticated и сохраняем ее результат в переменной isAuth.

Если пользователь аутентифицирован, isAuth будет true - в противном случае, false. Мы проверяем, не прошел ли пользователь аутентификацию (то есть, если isAuth равно false). Если нет, мы используем функцию redirect, чтобы отправить его обратно на главную или другую целевую страницу. Это эффективно предотвращает доступ неаутентифицированных пользователей к защищенному маршруту.

В качестве альтернативы мы можем рефакторить приведенный выше код для защиты маршрута Profile с помощью Higher Order Component (HOC), что является более чистым способом защиты маршрута на стороне клиента.

Чтобы использовать HOC, мы создадим файл в папке “components” под названием isAuth и добавим в него следующий код:

// isAuth.tsx

'use client';
import { isAuthenticated } from '@/Utils/Auth';
import { useEffect } from 'react';
import { redirect } from 'next/navigation';

export default function isAuth(Component: any) {
	return function IsAuth(props: any) {
		const auth = isAuthenticated;

		useEffect(() => {
			if (!auth) {
				return redirect('/');
			}
		}, []);

		if (!auth) {
			return null;
		}

		return <Component {...props} />;
	};
}

В приведенном выше коде определен компонент высшего порядка (isAuth), который проверяет статус аутентификации пользователя. Если пользователь не аутентифицирован, он предотвращает отрисовку защищенного компонента и перенаправляет его на домашнюю страницу.

Этот компонент высшего порядка будет использоваться для защиты маршрута “Dashboard” в нашем приложении путем обертывания им защищенного компонента, как показано ниже:

// dashboard/page.tsx

import isAuth from '@/Components/isAuth';

const Dashboard = () => {
	return <main className=" flex h-screen items-center justify-center">Панель управления</main>;
};

export default isAuth(Dashboard);

Приведенный выше код интегрирует HOC isAuth с компонентом Dashboard, гарантируя, что приборная панель защищена и доступ к ней могут получить только аутентифицированные пользователи. Если пользователь не прошел аутентификацию, он будет перенаправлен на другой маршрут, определенный HOC isAuth.

Ура! Мы успешно защитили наши маршруты на стороне клиента, используя useLayoutEffect и компоненты высшего порядка.

Защита маршрутов на стороне сервера

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

Защита маршрутов на стороне сервера не представляет собой ничего сложного. Мы можем согласиться с тем, что все компоненты в Next.js по умолчанию являются серверными компонентами. Вы можете защитить свои маршруты на стороне сервера, как показано ниже:

// admin/page.tsx

import { isAuthenticated } from '@/Utils/Auth';
import { redirect } from 'next/navigation';

const Admin = () => {
	const isAuth = isAuthenticated;

	if (!isAuth) {
		redirect('/');
	}
	return (
		<main className="flex h-screen items-center justify-center text-center">
			<div>
				<h1>Страница администратора</h1>
			</div>
		</main>
	);
};

export default Admin;

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

Защита маршрутов на основе промежуточного ПО

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

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

Среднее ПО позволяет перехватывать запросы и применять пользовательские правила, что делает его идеальным для применения строгих политик безопасности.

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

Мы собираемся защитить маршрут ”Настройки” с помощью middleware. Для этого мы создадим файл middleware.ts. Файл middleware принято создавать в корневой папке (на том же уровне, что и папка приложения или страницы) или в папке src, если это применимо.

Затем мы защитим наш маршрут Settings, добавив следующий код:

//middleware.ts

import { isAuthenticated } from '@/Utils/Auth';
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

const protectedRoutes = ['/settings'];

export default function middleware(req: NextRequest) {
	if (!isAuthenticated && protectedRoutes.includes(req.nextUrl.pathname)) {
		const absoluteURL = new URL('/', req.nextUrl.origin);
		return NextResponse.redirect(absoluteURL.toString());
	}
}

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

В приведенном выше коде функция isAuthenticated импортируется из модуля @/Utils/Auth. Эта функция отвечает за проверку статуса аутентификации пользователя. Если пользователь аутентифицирован, она возвращает true, в противном случае - false.

NextResponse и NextRequest являются частью API бессерверных функций Next.js для обработки HTTP-запросов и ответов.

Определяется массив protectedRoutes, содержащий путь(и) маршрута(ов), нуждающегося(ихся) в защите. В данном случае в него входит маршрут /settings. Функция промежуточного ПО выполняется перед обработкой запроса и служит промежуточным ПО, отвечающим за защиту маршрутов.

Внутри функции промежуточного ПО проверяется, не аутентифицирован ли пользователь (!isAuthenticated) и не совпадает ли запрашиваемый путь (req.nextUrl.pathname) с одним из защищенных маршрутов. Если оба условия выполнены, создается абсолютный URL, указывающий на корневой путь (”/”) приложения, с использованием нового URL (”/”, req.nextUrl.origin). Затем используется NextResponse.redirect для выполнения перенаправления на построенный абсолютный URL.

Заключение

Защита маршрутов - неотъемлемый аспект разработки веб-приложений, особенно при работе с конфиденциальными данными или ограничении доступа к определенным функциям.

В этом руководстве мы рассмотрели три комплексных метода защиты маршрутов в Next.js 13, обеспечивающих защиту неавторизованных пользователей. Применяя эти методы, вы сможете укрепить безопасность своего приложения и улучшить общий пользовательский опыт.

Благодаря знаниям, полученным из этого руководства, вы сможете защитить маршруты своего приложения Next.js, создав более безопасную и удобную работу. Независимо от того, какую защиту вы выберете - клиентскую, серверную или на основе промежуточного ПО, - цель остается неизменной: обеспечить целостность приложения и защитить данные пользователей.

Если у вас возникли вопросы или вам нужна дополнительная помощь, не стесняйтесь изучить дополнительные ресурсы или обратиться к сообществу Next.js. Вы также можете получить доступ к CodeSandbox для этого руководства здесь.

Удачного кодирования и безопасной маршрутизации в ваших приложениях Next.js!