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

ВВЕДЕНИЕ

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

Теперь, что, если по какой-либо причине (тайм-аут сеанса, просроченный файл 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



Ознакомьтесь с документацией