
Как сделать базовую аутентификацию в Vue.js с помощью Google Firebase
Иногда, как разработчики, мы хотим создать простой прототип, чтобы сделать MVP (продукт с минимальной стоимостью) нашей идеи стартапа. Если вы знаете основы использования Javascript и Vue.js, вы можете подготовить свою базу mvp за считанные минуты.
В этом проекте мы хотим подготовить базовую аутентификацию и решить, куда может перейти зарегистрированный пользователь, а где - гость. В этом решении я собираюсь использовать Google Firebase - смешанные сервисные инструменты для быстрого создания приложений без управления инфраструктурой.
Прежде чем мы начнем
Прежде чем мы начнем, вам нужно перейти на console.firebase.google.com и создать новый проект. После этого на начальном экране вы можете установить флажок Добавить Firebase в свое веб-приложение, а затем вы сможете увидеть конфигурацию javascript. СКОПИРОВАТЬ!
Затем подумайте о настройке вашего модуля Auth. На боковой панели выберите РАЗРАБОТКА - ›Аутентификация. Перейдите на карту СПОСОБ ВОЙТИ и настройте 3 метода: электронная почта / пароль, Google и Facebook. Следуйте инструкциям во всплывающих окнах для настройки свойств. Если возникла проблема, дайте мне знать в комментарии - я собираюсь подготовить видео об этом.
Шаг 1. Инициализируйте новый проект Vue
Чтобы запустить наш проект, я собираюсь использовать Vue CLI с шаблоном webpack. Все, что думает о CLI, можно найти здесь.
$ vue init webpack auth-project
Во время установки CLI спросит вас о названии проекта, описании, авторе и т. Д. Если вы хотите подготовить модульный тест или линтер - просто измените ответ на «да». Важно: установите Vue build для автономной и install Vue router для Yes.
? Project name auth-project ? Project description A Vue.js project ? Author Michal Jurkowski ? Vue build standalone ? Install vue-router? Yes ? Use ESLint to lint your code? No ? Set up unit tests No ? Setup e2e tests with Nightwatch? No ? Should we run `npm install` for you after the project has been created? (recommended) npm vue-cli · Generated “auth-project”.
Затем нам нужно войти в наш проект и установить дополнительные модули npm для использования Vuex (шаблон управления состоянием Vue), Firebase SDK и Firebase UI (встроенный компонент аутентификации firebase).
$ cd auth-project $ npm install vuex firebase firebaseui --save
Шаг 2. Подготовьте простые представления
Следующим шагом будет создание в нашем каталоге src нового каталога с именем views. Здесь мы хотим создать 3 простых представления: Home, Auth, Dashboard. В нашем проекте вы начнете дома - это представление доступно для всех пользователей и гостей. Оттуда вы можете перейти к логину - Auth, где вы можете выбрать метод Auth. Вид панели инструментов предназначен для зарегистрированных пользователей - важное ограничение.
Из src/components снимаю HelloWorld.vue - не надо работать свойство в нашем проекте.
Мои 3 компонента в src/views выглядят так:
# src/views/Home.vue
<template>
<div>
<h1>Hello!</h1>
<p>What you want to do?</p>
<router-link to="/auth">Sign in</router-link>
</div>
</template>
<script>
export default {
name: 'home'
}
</script>
<style scoped>
</style>
Как видите, я использую <router-link> для подготовки привязки к нашей странице авторизации.
# src/views/Auth.vue
<template>
<div>
<h1>Sign in</h1>
</div>
</template>
<script>
export default {
name: 'auth',
}
</script>
<style scoped>
</style>
На шаге 5 мы собираемся реализовать здесь пользовательский интерфейс Firebase.
И последний наш файл - Dashboard:
# src/views/Dashboard.vue
<template>
<div>
<h1>Hello USER!</h1>
</div>
</template>
<script>
export default {
name: 'dashboard'
}
</script>
<style scoped>
</style>
Шаг 3. Создайте простую маршрутизацию
Теперь нам нужно создать простую маршрутизацию с ограничениями. Посмотрите на наши маршруты - для /auth и /dashboard я добавляю дополнительное свойство meta с двумя ключами: guestOnly (если это правда и пользователь зарегистрирован, мы перенаправим его на просмотр для пользователя - например, если пользователь хочет перейти на страницу входа, если он зарегистрирован) и requireAuth (если это правда и пользователь не вошел в систему, мы должны перенаправить его на страницу входа).
Для лучшей практики я использую History Mode из HTML5. Более подробную информацию вы можете найти здесь.
# src/router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import Auth from '@/views/Auth'
import Dashboard from '@/views/Dashboard'
import Home from '@/views/Home'
Vue.use(Router)
var routes = [
{ path: '/home', name: 'home', component: Home },
{ path: '/auth', name: 'auth', component: Auth, meta: { guestOnly: true } },
{ path: '/dashboard', name: 'dashboard', component: Dashboard, meta: { requireAuth: true } },
{ path: '*', redirect: '/home' }
]
export const router = new Router({
mode: 'history',
routes
})
И теперь нам нужно подключить наш маршрутизатор к основному экземпляру Vue в main.js
import Vue from 'vue'
import App from '@/App'
import {router} from '@/router'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
template: '<App/>',
components: { App }
})
Шаг 4: Подготовьте Vuex Store
Теперь у нас есть готовый простой SPA (одностраничное приложение). Но прежде чем мы начнем работать с firebase, мы должны подготовить наш Магазин для пользовательских данных. Лучшая практика во Vue - это работа с хранилищами управления состоянием. Все о Vuex вы можете прочитать здесь.
Первая хорошая практика - сделать независимый пользовательский модуль для управления пользовательскими состояниями. Для этого я создаю простую файловую структуру src/store с основным хранилищем (index.js) и пользовательским модулем (modules/user.js).

В этом примере я поместил эту структуру, потому что она может помочь вам понять пространства имен и способы масштабирования вашего приложения. Каждый модуль - это своего рода хранилище данных. Если вы разделите каждый модуль, все изменения в вашем приложении могут быть проще.
# src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
},
getters: {
},
mutations: {
},
actions: {
},
modules: {
user
}
})
Как вы можете видеть в этом файле, я готовлю основной Vuex Store и помещаю пользовательский модуль.
# src/store/modules/user.js
import Vue from 'vue'
const state = {
user: null
}
const getters = {
user: state => state.user,
isLogged: state => (state.user !== null)
}
const mutations = {
setUser: (state, user) => {
state.user = user
}
}
const actions = {
}
export default {
namespaced: true,
state,
getters,
mutations,
actions
}
И теперь мы можем запустить наш магазин в main.js
# main.js
import Vue from 'vue'
import App from '@/App'
import {router} from '@/router'
import {store} from '@/store'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
store,
router,
template: '<App/>',
components: { App }
})
Шаг 5. Создайте класс аутентификации
Если вы настроите свой проект firebase (инструкция находится в начале этого поста), тогда мы можем начать создавать класс аутентификации. Мы собираемся сделать единый файл, в котором будут представлены все методы авторизации.
# src/auth.js
import firebase from 'firebase'
import firebaseui from 'firebaseui';
const config = {
apiKey: '#######',
authDomain: '#######',
databaseURL: '#######',
projectId: '#######',
storageBucket: '#######',
messagingSenderId: '#######'
};
const auth = {
context: null,
uiConfig: null,
ui: null,
init(context) {
this.context = context;
firebase.initializeApp(config);
this.uiConfig = {
signInSuccessUrl: 'dashboard',
signInOptions: [
firebase.auth.FacebookAuthProvider.PROVIDER_ID,
firebase.auth.GoogleAuthProvider.PROVIDER_ID,
firebase.auth.EmailAuthProvider.PROVIDER_ID
]
}
this.ui = new firebaseui.auth.AuthUI(firebase.auth());
firebase.auth().onAuthStateChanged((user) => {
this.context.$store.dispatch('user/setCurrentUser')
let requireAuth = this.context.$route.matched.some(record => record.meta.requireAuth)
let guestOnly = this.context.$route.matched.some(record => record.meta.guestOnly)
if(requireAuth && !user) this.context.$router.push('auth')
else if (guestOnly && user) this.context.$router.push('dashboard')
});
},
authForm(container) {
this.ui.start(container, this.uiConfig);
},
user() {
return this.context ? firebase.auth().currentUser : null;
},
logout() {
firebase.auth().signOut();
}
}
export default auth;
Не забудьте установить config с помощью ключей firebase.
Простое объяснение методов:
init(context) - мы хотим запустить его, когда приложение будет готово. Затем мы делаем доступ к основному экземпляру vue (предоставленному context) и инициализируем firebase и firebase ui с конфигурацией. Пользовательский интерфейс Firebase инициализируется тремя способами аутентификации - вход в Facebook, вход в Google и вход по электронной почте. И прикрепляем к объекту недвижимости на нашем сайте. Не забудьте установить signInSuccessUrl для перенаправления после входа в систему. Я прикрепляю дополнительный прослушиватель для состояния аутентификации пользователя - если он изменится, я хочу обновить информацию о пользователе в нашем магазине и посмотреть, где пользователь сейчас находится (маршрутизация) и может ли он там быть. Это ситуация, если пользователь вошел в систему и набрал в адресной строке /auth, чтобы принудительно открыть это представление. Это правило перенаправляет его на /dashboard, потому что он зарегистрирован.
authForm() - этот метод выполняет сборку пользовательского интерфейса Firebase в контейнере
user() - вернет текущий пользовательский объект, если он существует
logout() - это метод Firebase для выхода пользователя из системы
Но берегись! В init мы используем this.context.$store.dispatch('user/setCurrentUser'), но в магазине его нет! Итак, мы модифицируем src/store/modules/user.js
# src/store/modules/user.js
import Vue from 'vue'
import auth from '@/auth';
const state = {
user: null
}
const getters = {
user: state => state.user,
isLogged: state => (state.user !== null)
}
const mutations = {
setUser: (state, user) => {
state.user = user
}
}
const actions = {
setCurrentUser: ({ commit }) => {
commit('setUser', auth.user())
}
}
export default {
namespaced: true,
state,
getters,
mutations,
actions
}
Следующее, что нужно сделать, это обновить маршрутизатор, чтобы определить разрешения для гостей и пользователей.
# src/router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import auth from '@/auth'
import Auth from '@/views/Auth'
import Dashboard from '@/views/Dashboard'
import Home from '@/views/Home'
Vue.use(Router)
var routes = [
{ path: '/home', name: 'home', component: Home },
{ path: '/auth', name: 'auth', component: Auth, meta: { guestOnly: true } },
{ path: '/dashboard', name: 'dashboard', component: Dashboard, meta: { requireAuth: true } },
{ path: '*', redirect: '/home' }
]
export const router = new Router({
mode: 'history',
routes
})
router.beforeEach((to, from, next) => {
let currentUser = auth.user()
let requireAuth = to.matched.some(record => record.meta.requireAuth)
let guestOnly = to.matched.some(record => record.meta.guestOnly)
if (requireAuth && !currentUser) next('auth')
else if (guestOnly && currentUser) next('dashboard')
else next()
})
Я прикрепляю в конце файла router.beforeEach, чтобы проверить наши правила и перенаправить, если это необходимо.
И последнее место - это main.js, где мы должны запустить наш модуль аутентификации.
# src/main.js
import Vue from 'vue'
import App from '@/App'
import {router} from '@/router'
import {store} from '@/store'
import auth from '@/auth'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
store,
router,
beforeCreate () {
auth.init(this)
},
template: '<App/>',
components: { App }
})
Шаг 6. Сделайте вид Auth
Чтобы сделать представление Auth, мы должны подготовить для них контейнер и после монтирования выполнить authForm из класса auth. Кроме того, мы можем импортировать firebase ui css.
# src/views/Auth.vue
<template>
<div>
<h1>Sign in</h1>
<div id="firebaseui-auth-container"></div>
</div>
</template>
<script>
import auth from '@/auth'
export default {
name: 'auth',
mounted() {
auth.authForm('#firebaseui-auth-container')
}
}
</script>
<style>
@import "../../node_modules/firebaseui/dist/firebaseui.css";
</style>
После этого наше Auth View выглядит так:

Шаг 7. Отобразите сведения о пользователе в Личном кабинете
Последнее, что нужно подумать, - это подготовить представление Dashboard и поместить туда данные пользователя.
# src/views/Dashboard.vue
<template>
<div v-if="user">
<h1>Hello USER!</h1>
<img :src="user.photoURL" width="100"> <br>
<h3>{{user.displayName}}</h3>
<p>{{user.email}}</p>
<button @click="logOut">Log out</button>
<br><br><br>
<pre>{{user}}</pre>
</div>
</template>
<script>
import auth from '@/auth'
export default {
name: 'auth-success',
computed: {
user() {
return this.$store.getters['user/user']
}
},
methods: {
logOut() {
auth.logout()
}
}
}
</script>
<style scoped>
img {
border-radius: 50px;
}
h3 {
margin-bottom: 0;
}
p {
margin-top: 0;
}
pre {
text-align: left;
}
</style>
В итоге это выглядит так:

РЕЗЮМЕ
Как видите, этот прототип во Vue очень прост. Если вы используете какие-то внешние инструменты, такие как Firebase, вы можете сделать свои приложения очень быстрыми для простого распространения. Все исходники вы можете найти в публичном репозитории на Github.
Не стесняйтесь комментировать мое решение!