В этом руководстве мы будем работать над созданием простого приложения Vue.js. Он будет использовать Firebase для аутентификации и позволит пользователям регистрироваться. После регистрации пользователи получают доступ к защищенным областям веб-приложения через страницу входа.

Чтобы все было как можно проще и короче, предполагается, что вы знакомы с Vue.js. Вы можете начать работу с проектом, используя CLI и webpack. Мы проработаем две основные темы для создания нашего приложения:

  1. Использование vue-router 2 для загрузки и защиты страниц веб-приложения.
  2. Настройте серверную часть Firebase, которая использует аутентификацию Firebase для управления регистрацией и входом пользователей.

Учебные файлы можно бесплатно скачать на github. По возможности добавлены комментарии, объясняющие, что делает код. Чтобы сайт начал работать на вашем локальном компьютере, следуйте инструкциям в файле README. Основной каталог, в котором мы будем писать наш код, - это каталог «src. Если вы раньше создавали приложения Vue, это должно быть вам знакомо.

Архитектура приложения

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

Обработка маршрутов и защита страниц

Первое, что нужно понять - это как отправлять запросы страниц и защищать страницы, на которых выполняется вход. Для этого мы установим vue-router 2, стороннюю библиотеку для обработки маршрутов. Чтобы лучше понять простые маршруты, мы сначала проигнорируем защиту каких-либо страниц. Настроим структуру сайта:

  • Дом
  • Подписаться
  • Войти
  • Панель управления (в конечном итоге мы защитим эту страницу)
  • Ошибка / 404 (страница для всех)

Чтобы получить общее представление о том, что делает vue-router, необходимо просмотреть два основных файла. В файле main.js мы импортируем VueRouter и сообщаем Vue, что вы хотите использовать его. Затем мы создаем экземпляр VueRouter и передаем маршруты, которые приложение будет использовать, через отдельный файл routes.js.

Здесь мы также устанавливаем нам режим для маршрутизатора, из коробки vue-router будет загружать каждую страницу с хешем в URL-адресе. В современных браузерах мы можем использовать API истории HTML5 и избавиться от необходимости иметь хэш в URL-адресе.

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

Vue.use(VueRouter);
const router = new VueRouter({ routes: routes,  mode: 'history'} );

Файл routes.js импортирует все компоненты, которые вы будете отображать по всему сайту. Он экспортирует массив всех ваших маршрутов как объекты. Каждый объект имеет следующие пары ключ-значение:

  • название маршрута (необязательно)
  • путь (URL-адрес, по которому переходит пользователь)
  • компонент (компонент Vue для загрузки)

Чтобы объяснить немного больше, взгляните на следующий код:

{
 path: '/sign-in', // set the URL the user will visit
 name: 'signIn', // use this name as a shortcut in your links
 component: SignIn // load the SignIn component
}

Для каждого маршрута мы повторяем приведенный выше код и меняем свойства для всех вариантов маршрута. Затем мы добавим открывающий и закрывающий теги <router-view></router-view> в файл App.js. Они действуют как заполнители, сообщая Vue, где заменить компоненты при выборе пути маршрута. После этого вы сможете переходить к каждому URL-адресу, и компонент для этого пути загрузится.

Обеспечение безопасности маршрутов

Vue-router предоставляет возможность защищать маршруты с помощью Navigation Guards. Есть три уровня защиты, с которыми вы можете работать:

  • Глобальные охранники (которые мы будем использовать) устанавливаются один раз в экземпляре маршрута.
  • Охранники на маршруте устанавливаются на каждом маршруте отдельно.
  • Внутрикомпонентные ограждения установлены в каждом компоненте.

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

  1. Есть ли у маршрута мета-свойство, для которого requiresAuth установлено значение true.
  2. Пользователь вошел в систему и прошел аутентификацию с помощью аутентификации Firebase.

Давайте проработаем вышеупомянутые пункты, чтобы лучше понять, что происходит. У vue-router есть мета-поля маршрута, куда вы можете добавлять данные для извлечения для этого конкретного маршрута. Мы можем использовать это, чтобы установить простое логическое значение requiresAuth для наших защищенных страниц:

{
   path: '/dashboard',
   name: 'dashboard',
   component: Dashboard,
   meta: {
    requiresAuth: true
   }
},

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

router.beforeEach((to, from, next) => {
const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
if(requiresAuth) {
   next('/sign-in');
} else {
  next();
}
});

Здесь мы вызываем метод beforeEach на экземпляре маршрутизатора. Требуется 3 аргумента, подробно объясненных в документации, но главный, на котором нужно сосредоточиться, - это аргумент next. Здесь вы указываете маршрутизатору, что делать, если для условия requiresAuth установлено значение true.

В нашем приложении мы используем его для отправки пользователя на страницу входа. Чтобы получить доступ к метаданным маршрута, мы устанавливаем константу, которая принимает аргумент to (маршрут, по которому мы перемещаемся к). В документации объясняется, как вы можете получить доступ к установленным вами метаполям:

Все записи маршрута, соответствующие маршруту, отображаются в объекте $route (а также в объектах маршрута в средствах навигации) в виде массива $route.matched. Следовательно, нам нужно будет перебрать $route.matched, чтобы проверить мета-поля в записях маршрута.

Имея доступный нам мета-массив, мы можем перебирать его с помощью функции ES6:

const requiresAuth = to.matched.some(record => record.meta.requiresAuth);

Мы передаем requiresAuth в условное. Если true отправить пользователя на страницу входа, если false загрузить страницу как обычно.

Стоит потратить время на прочтение документации. Получите хорошее представление о том, что делает beforeEach метод. Это ключевой принцип для понимания охранников маршрута. Затем мы перейдем к использованию Firebase для аутентификации пользователя и добавим проверку для защиты маршрута.

Аутентификация с помощью Firebase

Firebase предлагает полную бэкэнд и систему аутентификации. Его можно добавить в интерфейсную часть вашего веб-приложения. В этой демонстрации мы будем использовать его API аутентификации, чтобы позволить пользователям регистрироваться и входить в систему. После входа в систему прошедшие аутентификацию пользователи могут просматривать защищенный контент. Первое, что вам нужно сделать, это зарегистрировать аккаунт на Firebase. Я также предлагаю посмотреть, как начать работу с Firebase Auth.

После того, как вы настроите учетную запись, вам нужно будет создать проект в Firebase. Вместо этого вы можете прочитать документацию по Firebase. Они предоставляют отличный набор инструкций для начала. Обратите внимание, что вам нужно будет скопировать и вставить настройки конфигурации и поменять их местами в main.js проекта. Убедитесь, что вы включили аутентификацию по электронной почте и паролю в качестве метода входа.

С настроенным Firebase и добавленными настройками конфигурации. Давайте посмотрим на заключительную часть процесса аутентификации. Добавьте второй условный оператор в созданный нами ранее метод beforeEach защитника маршрута.

router.beforeEach((to, from, next) => {
const currentUser = Firebase.auth().currentUser;
const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
if (requiresAuth && !currentUser) {
 next('/sign-in');
} else if (requiresAuth && currentUser) {
 next();
} else {
 next();
}
});

Мы добавили переменную currentUser, она возвращает текущего авторизованного пользователя из Firebase. Если никто не вошел в систему, возвращается значение null. Мы можем использовать это как вторую проверку в нашем условном выражении. Если оба параметра requiresAuth и currentUser истинны, маршрут отобразит страницу.

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

Убедитесь, что Firebase инициализирована перед загрузкой Vue

Наши маршруты настроены так, что если вы уже вошли в систему, вы будете перенаправлены на страницу панели инструментов. К сожалению, этого не произойдет. Выполнение навигационной защиты beforeEach происходит до завершения инициализации Firebase. Это очень важная ошибка, которую Анас Маммери объясняет в своем посте.

Использование Vue для обработки регистрации и входа в систему

Нам нужно, чтобы пользователи могли регистрироваться и входить в наше приложение. Взгляните на два компонента Vue SignUp.vue и SignIn.vue. Оба они работают одинаково, привязывая поля электронной почты и пароля к свойству данных.

Интеграция с Firebase происходит при запуске метода signUp или signIn. Эти функции предоставляются Firebase. Мы передаем адрес электронной почты и пароль из свойства данных Vue. В случае успеха перейдите на панель управления, используя метод замены vue-router. Если возникают какие-либо ошибки, отображается предупреждение с сообщением об ошибке.

signUp: function() {
  Firebase.auth()
          .createUserWithEmailAndPassword(this.email, this.password)
          .then( user => { this.$router.replace('dashboard'); },
          error => { alert(error.message); });
}
signIn: function() {
  Firebase.auth()
          .signInWithEmailAndPassword(this.email, this.password)
          .then( user => { this.$router.replace("dashboard"); },
          error => { alert(error.message); });
}

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

Разрешение пользователям выходить из системы

Взгляните на компонент Header.vue. Мы можем использовать метод Firebase signOut, который срабатывает, когда пользователь нажимает кнопку выхода. Затем перенаправьте их на страницу входа с помощью метода замены vue-router.

signOut: function() {
  Firebase.auth()
    .signOut()
    .then(() => {
      this.$router.replace('sign-in');
    });
}

Загрузите сайт в свой браузер и нажмите кнопку выхода. Теперь вы должны быть перенаправлены обратно на страницу входа.

Подведение итогов и дальнейшее обучение

В нашем приложении теперь есть базовая аутентификация Firebase с добавлением некоторых простых основ vue-router. Далее нам нужно посмотреть, как мы управляем состоянием пользователя. Состояние помогает отображать контент и ссылки в зависимости от того, вошел ли пользователь в систему. После просмотра нескольких вариантов было бы неплохо погрузиться в Vuex.