Вопрос или проблема
Я хочу защитить свою главную страницу, если пользователь не аутентифицирован, он не должен иметь к ней доступ. Пользователь аутентифицирован, если существует куки, если пользователь вошел в систему и пытается перейти на страницу входа, его нужно перенаправить на главную страницу, используя промежуточное ПО Next.js. Проблема в том, что если я перехожу между страницами, в данном случае на страницу входа, а затем вхожу в систему, я перенаправляюсь на страницу входа, как и ожидалось. Страница перед главной теперь является страницей входа; если я попытаюсь вернуться, я получаю сообщение слишком много перенаправлений
на экране на несколько секунд, прежде чем я перенаправлюсь на главную страницу, как и ожидалось. Я прикрепил скриншот моих запросов из вкладки сети, когда происходит эта проблема вкладка сети. Я застрял с этой проблемой на несколько дней, и это действительно раздражает.
import { NextRequest, NextResponse } from 'next/server';
export async function middleware(request: NextRequest, response:
NextResponse) {
const isUserLogged = request.cookies.get('chat_accessToken');
const pathname = request.nextUrl.pathname;
const authPaths = ['/login', '/register'];
if (
(isUserLogged && pathname == "https://stackoverflow.com/") ||
(isUserLogged && authPaths.includes(pathname) && pathname !== '/home/chats')
) {
return NextResponse.redirect(new URL('/home/chats', request.url));
}
if (!pathname.includes('/login') && !isUserLogged) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}
export const config = {
matcher: [
/*
* Совпадение со всеми путями запроса, кроме тех, что начинаются с:
* - api (API марщруты)
* - _next/static (статические файлы)
* - _next/image (файлы оптимизации изображений)
* - favicon.ico (файл фавикона)
*/
'/((?!api|_next/static|_next/image|favicon.ico).*)',
],
};
Я изменил условие, чтобы убедиться, что страница не перенаправляется сама на себя (не сработало).
Ответ или решение
Проблема бесконечных перенаправлений в Middleware Next.js
Ваша задача заключается в обеспечении защиты домашней страницы приложения на основе Next.js, чтобы пользователи, не авторизованные через cookie, не имели доступа к ней, а также в том, чтобы авторизованные пользователи не могли переходить на страницу логина. Рассмотрим причины бесконечных редиректов и способы их решения на примере вашего кода.
Понимание проблемы
Когда вы пытаетесь перейти на страницу логина и далее обратно, если AuthCookie присутствует, ваш middleware может излишне вызывать перенаправления, тем самым создавая нежелательные циклы. Это приводит к ошибке «Слишком много перенаправлений», которую вы наблюдаете.
Анализ кода middleware
Ваш код middleware выглядит следующим образом:
import { NextRequest, NextResponse } from 'next/server';
export async function middleware(request: NextRequest, response: NextResponse) {
const isUserLogged = request.cookies.get('chat_accessToken');
const pathname = request.nextUrl.pathname;
const authPaths = ['/login', '/register'];
if ((isUserLogged && pathname == 'https://stackoverflow.com/') ||
(isUserLogged && authPaths.includes(pathname) && pathname !== '/home/chats')) {
return NextResponse.redirect(new URL('/home/chats', request.url));
}
if (!pathname.includes('/login') && !isUserLogged) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}
export const config = {
matcher: [
'/((?!api|_next/static|_next/image|favicon.ico).*)',
],
};
Описание выявленных проблем
-
Некорректные условия перенаправления: В вашем коде необходимо более чёткое определение условий для перенаправления, чтобы избежать ситуаций, когда пользователь будет зациклен на страницах логина и/или домашней страницы.
-
Неправильные URL в условиях: В условии проверки на авторизацию у вас используется абсолютный URL (
'https://stackoverflow.com/'
), что, вероятно, является ошибкой. Вам следует сравнивать только относительные пути. -
Проблема с маршрутами: Некорректное определение маршрутов для разных страниц может привести к тому, что пользователь будет бесконечно перенаправляться.
Рекомендации по модификации кода
Вот несколько рекомендаций по улучшению вашего middleware:
import { NextRequest, NextResponse } from 'next/server';
export async function middleware(request: NextRequest) {
const isUserLogged = request.cookies.get('chat_accessToken');
const pathname = request.nextUrl.pathname;
const authPaths = ['/login', '/register'];
// Перенаправляем авторизованных пользователей, если они пытаются попасть на страницу логина
if (isUserLogged && authPaths.includes(pathname)) {
return NextResponse.redirect(new URL('/home/chats', request.url));
}
// Перенаправляем неавторизованных пользователей на страницу логина, если они пытаются зайти на защищённые страницы
if (!isUserLogged && !authPaths.includes(pathname)) {
return NextResponse.redirect(new URL('/login', request.url));
}
// Если условие перенаправления не выполнено, продолжаем обработку запроса
return NextResponse.next();
}
export const config = {
matcher: [
'/((?!api|_next/static|_next/image|favicon.ico).*)',
],
};
Дополнительные рекомендации
-
Логирование проблем: Для диагностики циклов перенаправления вы можете добавить логи с информацией о путях и статусах перенаправления, чтобы лучше понять, как ваше приложение себя ведёт.
-
Тестирование с разными состояниями: Убедитесь, что вы проверяете различные сценарии: авторизованный пользователь вне домашней страницы, неавторизованный пользователь на разных страницах и т.д.
-
Использование
Next.js
для управления состоянием аутентификации: В некоторых случаях может быть полезным передать информацию о состоянии аутентификации в контекст приложения для упрощения управления авторизацией на уровне компонента.
С этими изменениями и предложениями вы должны устранить проблему с бесконечными перенаправлениями и сделать ваше приложение более устойчивым к ошибкам.