Рубрики
Без рубрики

Контроль доступа к страницам с использованием React Router

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

Автор оригинала: Doyin Olarewaju.

Проблема

Когда я впервые начал с реагирования, у меня была проблема. Мне нужно было контролировать доступ к определенным страницам в спа-салоне, который я построил с использованием React и React Reader, и я не мог найти никаких библиотек, которые могли бы помочь мне с этим, поэтому я решил написать немного утилиту, чтобы помочь мне с этим вопросом. Я назвал это моим промежуточным программным обеспечением React Router. Сырный, верно?

Сценарий образца

Скажем, у меня есть два взгляда. Войти (), Dashboard admin () и Super Admin (). Для входа в систему я хочу только пользователей, которые в настоящее время не вошли в систему, чтобы просмотреть эту страницу. Админ должен быть замечен только админами и супер администраторами пользователями с ролью Super Admin.

Скажем, у меня есть мои маршруты настроить этот путь:

 console.log(a)}>
    
       } />
       } />
       } />
    

Промежуточное программное обеспечение

Мой код промежуточного программного обеспечения выглядит так

    routeToDisplay (middlewares = [], routeToVisit, directedFrom = '', extra = {}) {
    	const mware = {
        	privateRoute: (routeToVisit, directedFrom) => this.privateRoute(routeToVisit, ),
      		alreadyLoggedIn: (routeToVisit) => this.alreadyLoggedIn(routeToVisit),
            adminAccess: (routeToVisit) => this.adminAccess(routeToVisit),
            superAdminAccess: (routeToVisit, directedFrom) => this.superAdminAccess(routeToVisit, directedFrom),
        }
        let ret = null
       	try{
        	for (let i = 0; i < middlewares.length; i++) {
            	ret = mware[middlewares[i]](routeToVisit, directedFrom, extra)
                if (ret.status === false) {
                	break
                }
            }
            return ret.routeObject
        }catch(e){
        	//handle error here
        }
    }

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

routeToDisplay (middlewares = [], route, directedFrom = '/') {

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

RouteTovisit : Маршрут Пользователь желает посетить.

Директироваться : В случае, если разрешение не успешно, где мы направляем пользователя. Например, в случае частных маршрутов мы направляем пользователя обратно в систему.

Следующая строка имеет список доступных потенциальных гостей

const mware = {
        	privateRoute: (routeToVisit, directedFrom) => this.privateRoute(routeToVisit, ),
      		alreadyLoggedIn: (routeToVisit) => this.alreadyLoggedIn(routeToVisit),
            adminAccess: (routeToVisit) => this.adminAccess(routeToVisit),
            superAdminAccess: (routeToVisit, directedFrom) => this.superAdminAccess(routeToVisit, directedFrom),
        }

По сути, это просто список Admitwoares Maped в функцию, которая реализует протокол доступа к этому маршруту. Функция, которую она отображает, просто использует желаемую проверку нами, например, приваряет, будет проверять, вошел ли пользователь или нет и разрешить доступ или запретить доступ.

let ret = null
try{
  for (let i = 0; i < midwares.length; i++) {
    	ret = mware[midwares[i]](routeToVisit, directedFrom, extra)
       		if (ret.status === false) {
            	break
            }
    }
    	return ret.routeObject
    }catch(e){
    	//handle error here
    }

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

Поскольку я получаю массив с ограниченными возможностями, это означает, что я могу пройти несколько с ограниченными возможностями. Это для цикла может пройти через них, и все будет хорошо, пока статус правда, но как только будет обнаружен ложь, доступ будет отклонен доступ. Например, я могу пройти в приварении и администраторе. Частный маршрут может вернуть True и Adminaccess может вернуть ложь, доступ будет отказаться в этом случае.

Последняя строка Возврат Ret.routeObject Возвращает любой путь, которую функция возвращается мне. Дело в том, что если доступ должен быть отказан, функция вернет маршрут Redirect/>, который будет перенаправлять пользователь обратно в систему или в другом месте. Посмотрим, как выглядит одна или две функции.

privateRoute (component, pathname = '/') { 
    return (auth.fetchCurrentUser !== null
            ? this._getRouteReturn(true, component)
            : this._getRouteReturn(false,
              )
    )
  }

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

_GetRouterTurn ()

Прохождение статуса и компонент он должен отправить обратно. Вот что выглядит _getrouterturn

_getRouteReturn (status, routeObject) {
    return {status, routeObject}
  }

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

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

adminAccess (component, pathname = '/') {
//in my case i stored my allowed roles in array form in my db, yours could be different
    if (utils.arrayContains(role, 'admin')) {
      return this._getRouteReturn(true, component)
    }
    return this._getRouteReturn(false,
      )
  }

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

Я думаю, что это довольно прямо вперед.

Используя его на наших маршрутах

Теперь наши маршруты выглядели так, как это раньше

 console.log(a)}>
    
       } />
       } />
       } />
    

Давайте дадим немного макияж. Скажем, я экспортировал мою промежуточную программу по умолчанию из своего собственного класса. Я импортирую это так раньше

import middleware from './middleware'
 console.log(a)}>
    
       middleware.routeDisplay(['alreadyLoggedIn'],)
      } />
       middleware.routeDisplay(['privateRoute','adminAccess'],)} />
       middleware.routeDisplay(['privateRoute','superAdminAccess'],               )
        } />
    

Вот и все. Давайте посмотрим на код для всего промежуточного программного обеспечения ниже.

import React from 'react'
import {
    Redirect
} from 'react-router-dom'
import auth from './stores/authenticationStore'
import utils from './stores/utils'

class Middleware {
  routeToDisplay (middlewares = [], routeToVisit, directedFrom = '', extra = {}) {
    	const mware = {
        	privateRoute: (routeToVisit, directedFrom) => this.privateRoute(routeToVisit, ),
      		alreadyLoggedIn: (routeToVisit) => this.alreadyLoggedIn(routeToVisit),
            adminAccess: (routeToVisit) => this.adminAccess(routeToVisit),
            superAdminAccess: (routeToVisit, directedFrom) => this.superAdminAccess(routeToVisit, directedFrom),
        }
        let ret = null
       	try{
        	for (let i = 0; i < middlewares.length; i++) {
            	ret = mware[middlewares[i]](routeToVisit, directedFrom, extra)
                if (ret.status === false) {
                	break
                }
            }
            return ret.routeObject
        }catch(e){
        	//handle error here
        }
    }
    
    _getRouteReturn (status, routeObject) {
      return {status, routeObject}
    }
    
    adminAccess (component, pathname = '/') {
    //in my case i stored my allowed roles in array form in my db, yours could be       different
        if (utils.arrayContains(role, 'admin')) {
          return this._getRouteReturn(true, component)
        }
        return this._getRouteReturn(false,
          )
      }
      
      privateRoute (component, pathname = '/') { 
        return (auth.fetchCurrentUser !== null
                ? this._getRouteReturn(true, component)
                : this._getRouteReturn(false,
                  )
        )
      }
}