- En esta lección del curso de Vue-Firebase implementaremos la protección de nuestras rutas con un "Router Guard" de Vue Router. Si esto de Vue Router es algo confuso para ti, no te preocupes, en Escuela Vue tienes un curso de Vue Router disponible 😼.
- Primero, tenemos que designar cual de las (dos por ahora) rutas requiere algún tipo de autentificación. En nuestro caso, renombramos
Home.vue
a RoomsView.vue
como portada del proyecto. Como el nombre indica, aquí mostraremos las salas de conversación disponibles.
- En
router/index.js
debemos indicar el nuevo nombre, y con los metadatos de las rutas expresar que requiere autentificación a través de la propiedad requiresAuth
como true
.
...
path: "/",
name: "home",
component: RoomsView,
meta: {
requiresAuth: true
}
...
- Ahora necesitamos crear un mecanismo para que, en el caso de que se intente acceder a
/
sin estar autentificado, el usuario/a sea redireccionado a /auth
para mostrar la vista AuthView.vue
. Conseguiremos esto en dos pasos.
- El primero, creando una acción en el módulo
user.js
de Vuex que nos permita comprobar si hay un usuario validado a través del ya conocido método onAuthStateChanged
que vimos en una lección anterior. Esta acción, llamada getCurrentUser
usará Promises E6 (siento ser pesado, pero si no tienes claro lo que son las promesas, en Escuela Vue tienes un magnífico curso de JavaScript moderno donde te explico como funcionan).
getCurrentUser() {
return new Promise((resolve, reject) => {
const unsubscribe = auth.onAuthStateChanged(
user => {
unsubscribe();
resolve(user);
},
() => {
reject();
}
);
});
},
- Como ves,
onAuthStateChanged
retorna una función para anular la suscripción al evento de cambio de auth, por lo si la guardamos en una variable, podemos ejecutarla para cancelar todo y no provocar errores de memoria. Más adelante usaremos un patrón similar con las escuchas a Cloud Firestore.
- Si no hay error, resolvemos retornando el usuario (que puede contener información o no, dependiendo si hay alguien autentificado) y anulamos la suscripción. Si hay algún error, rechazamos al promesa.
- El segundo paso es implementar nuestra
getCurrentUser
de forma que sea consultado cada vez que cargamos una ruta. Para ello usaremos el guard beforeEach
y establecemos condiciones en base a si la ruta requiere autentificación y/o el usuario/a está autentiticado, y viceversa.
router.beforeEach(async (to, from, next) => {
const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
if (requiresAuth && !(await store.dispatch("user/getCurrentUser"))) {
next({ name: "auth" });
} else if (!requiresAuth && (await store.dispatch("user/getCurrentUser"))) {
next({ name: "home" });
} else {
next();
}
});
- Con los dos pasos listos, si ahora intentamos acceder a
/
sin estar autentificados, nos devolverá a /auth
. De igual manera, si queremos acceder a /auth
estando autentificados, nos enviará a /
.