# AUTH Firebase (Vue.js 2)
Configurar auth en nuestra aplicación de Vue.
# Instalaciones
vue create auth-firebase (seleccionar vuex/router/babel)
cd auth-firebase
npm i firebase
# Vue.js devtools (opcional)
# Firebase
Inicilizar app en consola
import firebase from 'firebase/app'
import 'firebase/auth'
import 'firebase/firestore'
var firebaseConfig = {
apiKey: "xxx",
authDomain: "xxx",
databaseURL: "xxx",
projectId: "xxx",
storageBucket: "xxx",
messagingSenderId: "xxx",
appId: "xxx"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
const db = firebase.firestore()
const auth = firebase.auth()
export {db, auth}
# Ruta Registro
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/registro',
name: 'Registro',
component: () => import(/* webpackChunkName: "about" */ '../views/Registro.vue')
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
# Registro.vue
<template>
<div>
<h1>Registro de usuarios</h1>
<form>
<input
type="email"
placeholder="Ingrese email"
v-model="email"
>
<input
type="password"
placeholder="Ingrese contraseña"
v-model="pass1"
>
<input
type="password"
placeholder="Repita contraseña"
v-model="pass2"
>
<button type="submit">Registrar</button>
</form>
</div>
</template>
<script>
export default {
name: 'Registro',
data(){
return{
email: '',
pass1: '',
pass2: ''
}
}
}
</script>
# store
https://firebase.google.com/docs/auth/web/start?hl=es-419#sign_up_new_users (opens new window)
import Vue from 'vue'
import Vuex from 'vuex'
import {auth} from '../firebase'
import router from '../router'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
usuario: null,
error: null
},
mutations: {
setUsuario(state, payload){
state.usuario = payload
},
setError(state, payload){
state.error = payload
}
},
actions: {
crearUsuario({commit}, usuario){
auth.createUserWithEmailAndPassword(usuario.email, usuario.password)
.then(res => {
console.log(res)
const usuario = {
email: res.user.email,
uid: res.user.uid
}
commit('setUsuario', usuario)
router.push('/')
})
.catch(error => {
console.log(error)
commit('setError', error)
})
}
},
modules: {
}
})
# mapAction, mapState
<template>
<div>
<h1>Registro de usuarios</h1>
<form @submit.prevent="crearUsuario({email: email, password: pass1})">
<input
type="email"
placeholder="Ingrese email"
v-model="email"
>
<input
type="password"
placeholder="Ingrese contraseña"
v-model="pass1"
>
<input
type="password"
placeholder="Repita contraseña"
v-model="pass2"
>
<button type="submit">Registrar</button>
</form>
<p>{{error}}</p>
</div>
</template>
<script>
import {mapActions, mapState} from 'vuex'
export default {
name: 'Registro',
data(){
return{
email: '',
pass1: '',
pass2: ''
}
},
created(){
},
methods:{
...mapActions(['crearUsuario'])
},
computed:{
...mapState(['error'])
}
}
</script>
# Contraseñas
computed:{
...mapState(['error']),
desactivar(){
return this.pass1 === this.pass2 && this.pass1.trim() !== ''
}
}
<button type="submit" :disabled='!desactivar'>Registrar</button>
# Inicio.vue
<template>
<div>
<h1>Ruta protegida</h1>
</div>
</template>
<script>
export default {
name: 'Inicio'
}
</script>
# Ingreso.vue
<template>
<div>
<h1>Ingreso de usuarios</h1>
<form @submit.prevent="ingresoUsuario({email:email, password:pass})">
<input
type="email"
placeholder="Ingrese email"
v-model="email"
>
<input
type="password"
placeholder="Ingrese contraseña"
v-model="pass"
>
<button type="submit">Acceder</button>
</form>
<p>{{error}}</p>
</div>
</template>
<script>
import { mapActions, mapState } from 'vuex'
export default {
name: 'Ingreso',
data() {
return {
email: '',
pass: ''
}
},
created(){
},
methods:{
...mapActions(['ingresoUsuario'])
},
computed:{
...mapState(['error'])
}
}
</script>
# ingresoUsuario
https://firebase.google.com/docs/auth/web/start?hl=es-419#sign_in_existing_users (opens new window)
ingresoUsuario({commit}, usuario){
auth.signInWithEmailAndPassword(usuario.email, usuario.password)
.then(res => {
console.log(res)
const usuario = {
email: res.user.email,
uid: res.user.uid
}
commit('setUsuario', usuario)
router.push('/')
})
.catch(error => {
console.log(error)
commit('setError', error)
})
}
# store
// actions
detectarUsuario({commit}, usuario){
commit('setUsuario', usuario)
}
# main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
import {auth} from './firebase'
auth.onAuthStateChanged(user => {
if(user){
console.log(user)
store.dispatch('detectarUsuario', {email: user.email, uid: user.uid})
}else{
console.log(user)
store.dispatch('detectarUsuario', user)
}
})
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
# Inicio.vue
<template>
<div>
<h1>Ruta protegida</h1>
<p>{{usuario}}</p>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
name: 'Inicio',
computed:{
...mapState(['usuario'])
}
}
</script>
# Cerrar sesión
https://firebase.google.com/docs/auth/web/password-auth#next_steps (opens new window) Store
// actions
cerrarSesion({commit}){
auth.signOut()
router.push('/ingreso')
}
App.vue
<template>
<div id="app">
<div id="nav">
<router-link to="/registro">Registro</router-link> |
<router-link to="/ingreso">Ingreso</router-link> |
<router-link to="/">Inicio</router-link> |
<button @click="cerrarSesion">Cerrar Sesión</button>
</div>
<router-view/>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
methods:{
...mapActions(['cerrarSesion'])
}
}
</script>
# Router Guard (documentación)
https://router.vuejs.org/guide/advanced/meta.html#route-meta-fields (opens new window)
Ejemplo Route Meta Fields
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
children: [
{
path: 'bar',
component: Bar,
// a meta field
meta: { requiresAuth: true }
}
]
}
]
})
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
// this route requires auth, check if logged in
// if not, redirect to login page.
if (!auth.loggedIn()) {
next({
path: '/login',
query: { redirect: to.fullPath }
})
} else {
next()
}
} else {
next() // make sure to always call next()!
}
})
Ejemplo Global before Guards https://router.vuejs.org/guide/advanced/navigation-guards.html (opens new window)
router.beforeEach((to, from, next) => {
if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
else next()
})
# Rutas protegidas
import Vue from 'vue'
import VueRouter from 'vue-router'
import {auth} from '../firebase'
Vue.use(VueRouter)
const routes = [
{
path: '/registro',
name: 'Registro',
component: () => import(/* webpackChunkName: "about" */ '../views/Registro.vue')
},
{
path: '/',
name: 'Inicio',
component: () => import(/* webpackChunkName: "about" */ '../views/Inicio.vue'),
meta: { requiresAuth: true }
},
{
path: '/ingreso',
name: 'Ingreso',
component: () => import(/* webpackChunkName: "about" */ '../views/Ingreso.vue')
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
const usuario = auth.currentUser
console.log(usuario)
if (!usuario) {
next({
path: '/Ingreso'
})
} else {
next()
}
} else {
next()
}
})
export default router
main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
import {auth} from './firebase'
auth.onAuthStateChanged(user => {
if(user){
console.log(user)
store.dispatch('detectarUsuario', {email: user.email, uid: user.uid})
}else{
console.log(user)
store.dispatch('detectarUsuario', user)
}
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
})
# Getters
getters:{
existeUsuario(state){
if(state.usuario === null){
return false
}else{
return true
}
}
},
App.vue
<template>
<div id="app">
<div id="nav">
<router-link to="/registro" v-if="!existeUsuario">Registro</router-link> |
<router-link to="/ingreso" v-if="!existeUsuario">Ingreso</router-link> |
<router-link to="/" v-if="existeUsuario">Inicio</router-link> |
<button @click="cerrarSesion" v-if="existeUsuario">Cerrar Sesión</button>
</div>
<router-view/>
</div>
</template>
<script>
import { mapActions, mapGetters } from 'vuex'
export default {
methods:{
...mapActions(['cerrarSesion'])
},
computed:{
...mapGetters(['existeUsuario'])
}
}
</script>