Разделение доступа

ОБНОВЛЕНИЕ 2018: в учебнике хорошая теория, но ему уже два года. Проверяйте версии пакетов. За выходом нового учебника можно следить в telegram канале или twitter

На канале так же проводятся бесплатные вебинары, публикуются переводы и авторские материалы, присоединяйтесь!

Разделение доступа

В данном разделе, по шагам будет разобран вход на сайт в качестве администратора. Следовательно, мы сделаем недоступным для посещения адрес localhost:3000/admin, а так же рассмотрим редирект на "главную" или в "админку" после ввода логина.

Создадим страницу логина.

В качестве "сервера для авторизации", будем использовать localStorage.

Алгоритм простой: вводится логин - кладется в localStorage.

src/components/Login/index.js

import React, { Component } from 'react'

export default class Login extends Component {
  handleSubmit(e) {
    e.preventDefault()
    const value = e.target.elements[0].value
    window.localStorage.setItem('rr_login', value)
  }
  render() {
    return (
      <div className='row'>
        <div className='col-md-12'>Пожалуйста, введите логин:</div>
        <form className='col-md-4' onSubmit={this.handleSubmit}>
          <input type='text' placeholder='login'/>
          <button type='submit'>Войти</button>
        </form>
      </div>
    )
  }
}

src/routes.js

src/containers/App/index.js

Напоминаю: несмотря на то, что ссылка появилась в шапке (hot-reload работает для компонента <App />), страницу все равно нужно перезагрузить (так как hot-reload не работает для обновления списка роутов).

login_max_screen

Если ввести новый "логин" - старый перетирается. Данное допущение сейчас не мешает нам проверить работоспособность, а наоборот облегчает проверку.

Нам необходимо закрыть доступ "не админам", для этого потребуется разобрать "события", которые возникают в процессе изменений URL'a.

onEnter, onLeave

Предлагаю добавить слово "хук" в словарь. По-моему, хук, не что иное как "действие на событие".

Итак, есть возможность использовать хуки на события onLeave и onEnter. По названию понятно: onLeave возникает, когда "роут покинут", а onEnter - в момент "захожу на роут".

Представьте адрес:

react-site.com/profile/photos/

его "роутер-реализацию": (не стоит так говорить в приличном месте)

/ + profile + photos

и его реализацию компонентами:

<App /> + <Profile /> + <Photos />

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

  • onLeave на /profile/photos

  • onLeave на /profile

  • onEnter на /

И обратная ситуация: вы находитесь на главной, и решили перейти в раздел фото:

  • onLeave на /

  • onEnter на /profile

  • onEnter на /profile/photos

Вернемся к "хукам".

Добавьте в routes.js функцию checkLogin и непосредственно сам хук.

src/routes.js

Теперь если вы залогинетесь как admin - в консоли браузера вас "пропустят". Причем, заметьте, хук сработает при вводе url напрямую в строке ввода адреса + enter, либо если вы кликнете по ссылке. Так же, если вы уже находитесь в разделе admin и попробуете кликнуть на ссылку "Админка" - onEnter не произойдет, а следовательно и хук не сработает. Кажется, разработчики react-router'a постарались на славу.

login_admin_screen

На всякий случай, напоминаю, что очистить localStorage можно командой localStorage.clear()

У хука есть полезные аргументы - nextState, replace, callback. Нам понадобится replace. На пару слов подробнее можно прочитать в офф.документации.

Перепишем функцию checkLogin

src/routes.js

Попробуйте сейчас залогиниться под другим именем: вы не сможете войти на страницу /admin, независимо от того введете ли вы адрес и нажмете enter, или кликните по ссылке.

Страницу API Reference настоятельно рекомендую добавить в закладки.

Использование static method в качестве хука на onEnter

Наш код работает, но функция checkLogin, как будто мешается в файле с роутами. Может быть вынести ее в отдельный файл? А вы знаете, есть еще одно интересное решение: использовать static метод класса Admin.

src/components/Admin/index.js

Исправим routes.js (привожу полный листинг)

src/routes.js

Все, теперь с чистой совестью можете приступать к задачке на повторение.

Задача: если пользователь ввел admin - после нажатия кнопки "Войти" - направить его на /admin, иначе на /

Подсказка #1: Если данная задача вызвала у вас трудность, прочитайте еще раз предыдущую главу.

Решение:

src/components/Login/index.js

Итого: мы познакомились с возможностью "вклиниваться" в процесс роутинга. Разобрали рабочую ситуацию: как ограничить доступ юзеру в раздел администратора. Закрепили знания по программной навигации.

Исходный код на данный момент.

Last updated

Was this helpful?