В сегодняшней статье я покажу вам, как настроить автоматическое перенаправление на защищенную/ограниченную страницу в вашем приложении реагирования после аутентификации пользователя.
ВВЕДЕНИЕ
Предположим, что в вашем приложении есть страница, которая требует аутентификации, прежде чем пользователь сможет получить к ней доступ, например, панель инструментов. Это означает, что прежде чем пользователю будет разрешен доступ к панели управления, он должен войти в систему.
Теперь, что, если по какой-либо причине (тайм-аут сеанса, просроченный файл cookie и т. д.) пользователь выходит из приложения, но ему нужно повторно посетить ту же страницу на панели инструментов? Или, может быть, он пытается посетить информацию на панели инструментов, нажав на ссылку из письма, отправленного ему по электронной почте? Как бы вы перенаправили этого пользователя обратно на ссылку, которую он пытался посетить после аутентификации?
Этот вопрос сразу заставит вас понять, что недостаточно попросить пользователя войти в систему, прежде чем он сможет получить доступ к странице с ограниченным доступом. Но вы также должны перенаправить пользователя на страницу с ограниченным доступом сразу после его аутентификации.
ВСЕ ЕЩЕ ЗАПУТАН? ПОЗВОЛЬТЕ МНЕ ОБЪЯСНИТЬ ЛУЧШЕ
Итак, у меня есть эта страница http://my-website.com/dashboard/update-profile
, которая требует аутентификации пользователя, прежде чем ему будет разрешено посещать ее. Всякий раз, когда пользователь, не прошедший проверку подлинности, пытается посетить его, он будет перенаправлен на http://my-website.com/login
Теперь цель состоит в том, чтобы сохранить этот URL-адрес http://my-website.com/dashboard/update-profile
, чтобы после успешной аутентификации пользователя он был перенаправлен обратно на него.
Я покажу вам, как вы можете добиться этого в своем приложении React, и если вы понимаете логику, вы можете реализовать это где угодно!
ИСПОЛЬЗОВАНИЕ ПАРАМЕТРА ЗАПРОСА
В этом подходе я проверю, не вошел ли пользователь в систему, затем извлеку URL-адрес, который он пытается посетить, сохранит его в параметре запроса next
, а затем перенаправлю его на страницу входа. Если аутентификация пройдет успешно, я перенаправлю его обратно на URL-адрес в параметре запроса next
.
Поместите этот код на защищенную/ограниченную страницу (страницу, требующую аутентификации)
Для этого первое, что мне нужно сделать, это проверить, не вошел ли пользователь в систему.
useEffect(() => { isAuthenticated().then(res => { //check if user is not logged in if(!res){ //---- } } }, []) //make the function run only once when the component mounts
Теперь нам нужно создать новый объект URL со ссылкой, на которую будет перенаправлен этот пользователь для аутентификации.
В моем случае это будет страница /login
, и причина, по которой я создаю для нее новый объект URL, заключается в том, что я собираюсь манипулировать ссылкой, добавляя параметр запроса позже.
useEffect(() => { isAuthenticated().then(res => { //check if user is not logged in if(!res){ //create a URL object with the Login Link const loginUrl = new URL('http://my-website.com/login'); } } }, []) //make the function run only once when the component mounts
Теперь, прежде чем мы продолжим, нам нужно убедиться, что пользователь пытается посетить страницу с ограниченным доступом на панели инструментов. Мы можем сделать это, проверив, содержит ли текущий URL /dashboard
.
Я буду использовать регулярное выражение внутри метода match
для выполнения этого поиска по текущему URL-адресу.
useEffect(() => { isAuthenticated().then(res => { //check if user is not logged in if(!res){ //create a URL object with the Login Link const loginUrl = new URL('http://my-website.com/login'); //check if user is trying to access dashboard without logging in if(window.location.href.match(new RegExp('/dashboard', 'i'))){ //--- } } } }, []) //make the function run only once when the component mounts
Теперь нам нужно добавить ссылку, которую пользователь пытался посетить, в качестве параметра запроса к объекту URL, который мы создали ранее, а затем перенаправить пользователя на полный URL из этого объекта URL.
useEffect(() => { isAuthenticated().then(res => { //check if user is not logged in if(!res){ //create a URL object with the Login Link const loginUrl = new URL('http://my-website.com/login'); //check if user is trying to access dashboard without logging in if(window.location.href.match(new RegExp('/dashboard', 'i'))){ //Get the url he wanted to visit const next = window.location.href //append it to the URL object loginUrl.searchParams.append('next', next); } //redirect the user to the full URL from the URL Object window.location.href = loginUrl.href.toString() } } }, []) //make the function run only once when the component mounts
Вот что мы сделали на данный момент.
Когда пользователь, не прошедший проверку подлинности, попытается посетить любую страницу панели инструментов, например http://my-website.com/dashboard/update-profile
, он будет перенаправлен на http://my-website.com/login?next=http://my-website.com/dashboard/update-profile
.
Вот что нужно иметь в виду.
Браузер попытается закодировать значение в параметре запроса next
, потому что это URL-адрес, и прежде чем мы получим это значение, нам нужно его декодировать.
С моей стороны, вот как выглядит моя адресная строка
Пришло время нам обработать перенаправление, если пользователь аутентифицируется.
ОБРАБОТКА ПЕРЕНАПРАВЛЕНИЯ
Теперь на вашей странице входа мы создадим переменную, в которой будет храниться ссылка по умолчанию, на которую будет перенаправлен пользователь в случае успешной аутентификации.
Мы также импортируем useLocation
из react-router-dom
, чтобы мы могли прочитать текущий URL-адрес и проверить, содержит ли он параметр поиска (запроса).
import {useLocation} from 'react-router-dom'; export default function Login(){ //invoke the function const location = useLocation(); //default page to redirect user after login let redirect = 'http://my-website.com/dashboard/home'; //check if there's search param in the URL if(location.search){ //--- } }
Если вы не хотите использовать модуль useLocation
для чтения текущего URL-адреса, вы также можете получить доступ к текущему URL-адресу напрямую с помощью JavaScript.
export default function Login(){ //default page to redirect user after login let redirect = 'http://my-website.com/dashboard/home'; //create a URL object using the current url const url = new URL(window.location.href) //check if url contains a search parameter if(url.search){ //--- } }
Какой бы метод вы ни выбрали, следующее, что нужно сделать, это прочитать параметры поиска и проверить, содержит ли он next
.
Если он содержит next
, мы декодируем значение и переназначаем значение переменной redirect
этому URL.
Вы также можете выполнить поиск, чтобы проверить, содержит ли декодированное значение /dashboard
.
export default function Login(){ //default page to redirect user after login let redirect = 'http://my-website.com/dashboard/home'; //create a URL object using the current url const url = new URL(window.location.href) //check if url contains a search parameter if(url.search){ //read the search parameters const search = new URLSearchParams(url.search) //check if next parameter is present if(search?.get('next')){ //decode it const next = decodeURIComponent(search.get('next')) //check if dashboard is present in the URL if(next.match(new RegExp('/dashboard', 'i'))){ redirect = next; } } } //after authentication, redirect users to the redirect variable //window.location.href = redirect; }
Поэтому после аутентификации вы должны перенаправить своих пользователей на значение переменной redirect
, которое является декодированным URL-адресом!
Посмотрите мою реализацию ниже
НЕБОЛЬШОЙ СОВЕТ
Если вы хотите сделать свои перенаправления более чистыми, вы можете сохранить URL-адрес в sessionStorage
браузера, и когда вы его проверите, вы можете удалить его из хранилища сеанса, а затем перенаправить пользователя на URL-адрес.
Спасибо за чтение.
Тсс! Я открыт для выступлений по веб-разработке и техническому письму!
ДОПОЛНИТЕЛЬНЫЙ
Я создал библиотеку JavaScript, способную проверять ваши интерфейсные формы с помощью регулярных выражений, правил проверки и входных атрибутов формы.
Проверьте эту библиотеку на GitHub
Ознакомьтесь с документацией