Documentos de Académico
Documentos de Profesional
Documentos de Cultura
. . .
Vuejs y JWT
Seguramente eres un usuario ya experimentado o simplemente un nuevo
usuario que está aprendiendo Vuejs; este famoso y…
medium.com
Ya hemos tenido una introducción sobre vuejs y jwt. Así que ahora iremos al grano, sin
antes no responder algunas posibles preguntas que yo me hacia al momento de iniciar
con vue y jwt
Si eres un novato, y es primera vez que vas a usar jwt desde frontend, te recomiendo la
siguiente lectura, si no, pasa directamente a la explicación
En realidad sí, ten en cuenta que siempre que uses jwt con cualquier tecnología /
framework de javascript, el servidor si y solo sí, te solicitará verififcación mediante
https://medium.com/@deskevinmendez/agrando-jwt-a-vuejs-204f082391f 1/17
28/6/2020 Agregando JWT a Vuejs - Kevin Mendez - Medium
Supongamos que tenemos 4 rutas, una de login, otra de register, una de logout, y otra
que obtiene los blogs; el servidor te solicitará el tokens cada vez que hagas una peticion
http a toda aquella ruta que en el servidor esté configurada con jwt, es decir,
nosotros en frontend no vamos a complicarnos con esto, enviaremos una petición, si
existe el tokens lo enviamos, y si no, la petición siempre se hará, a que rutas
enviaremos el tokens, esta definido en el backend. Ten eso siempre en cuenta, para
evitar posibles confusiones.
¿El login necesita tokens? pues no, en este caso el login no necesita que exista un
tokens en frontend porque no tiene sentido que el servidor nos esté pidiendo un tokens
que él aún no ha solicitado, entonces, la petición llegara al servidor, el servidor nos
logeara, nos devolverá el tokens, lo recibimos y almacenamos en el front. Es así de
sencillo, no requiere de nada más.
¿El register necesita tokens? El mismo cuento que el login, no tiene sentido que el
register nos esté solicitando un tokens que él no ha generado.
¿El logout y los blogs necesita tokens? En esté caso sí, debido a que estas rutas si
están configuradas en el backend para que nos pida un tokens ya generado por nuestro
servidor. Al momento de hacer logout nos lo pedirá pero por qué: esto es debido a que
el único que puede hacer logout es ya un usuario logeado, es simplemente por lógica
que lo tiene que solicitar para poder destruir la sesión en el backend; y el de blogs, es el
mismo cuento, debido a que solo los usuarios logeado pueden ver los blogs publicados,
al no ser que quieras que los blogs creados por usuarios sea accesible a cualquier
persona que visite nuestro sitio web, en ese caso, como no es necesario que este un
usuario logeado, no será necesario el envio de tokens cada vez que alguien desee ver
nuestras publicaciones.
El frontend está conectado con el backend, el front realiza las peticiones al backend, y
éste responde con la información solicitada, y es aquí cuando se verifica si un usuario
esta logeado, ¿cómo lo hace? lo que realmente sucede es que el backend verifica un
hash generado por el mismo, que está recibiendo desde nuestro app frontend. Si esté
https://medium.com/@deskevinmendez/agrando-jwt-a-vuejs-204f082391f 2/17
28/6/2020 Agregando JWT a Vuejs - Kevin Mendez - Medium
tokens ha experido el servidor nos devolvera un error http 403, nosotros en frontend
capturamos este error, (Puede ser cualquier otro, dependiendo la configuración hecha
en el backend); y así saber cuando ha caducado una sesión, y realizar lo que les sea
conveniente, como redireccionar al login por ejemplo, o tomar este tokens expirado y
renovarlo.
Hay dos cosas que pueden pasar al momento que el tokens ha expirado:
Ahora es posible que te preguntes que si por qué traigo esto a cuenta; pero es
simplemente para aclarar que estás cosas no nos debe de preocupar en nuestro
frontend, porque son tareas que son realizadas desde el servidor; y nuestra única
responsabilidad es enviar el tokens, una vez lo tengamos disponible. Sabiendo esto, nos
evitarnos algunos dolores de cabeza.
Puede seguir está guía por si aún no estás familiarizado con vue-cli
. . .
https://medium.com/@deskevinmendez/agrando-jwt-a-vuejs-204f082391f 3/17
28/6/2020 Agregando JWT a Vuejs - Kevin Mendez - Medium
2. npm i axios
'bootstrap/dist/css/bootstrap.min.css';
Con estas librerías, ya estamos listos para empezar a codificar las vistas.
1 <template>
2 <div class="container" style="max-with: 100vh;">
3 <h1>Example vue with laravel and jwt</h1>
4 <div>
5 This project, show a little example of how run jwt from laravel to vuejs
6 Is a basic example, please, any question, let it in comments; or send tweet a @ke
7 Follow me!
8 </div>
9 </div>
10 </template>
1 <template>
2 <div class="home">
3 <div class="wrapper fadeInDown">
4 <div id="formContent">
5 <!-- Tabs Titles -->
6
7 <!-- Icon -->
8 <div class="fadeIn first">
9 <img :src="img" id="icon" alt="User Icon" />
10 </div>
11
https://medium.com/@deskevinmendez/agrando-jwt-a-vuejs-204f082391f 4/17
28/6/2020 Agregando JWT a Vuejs - Kevin Mendez - Medium
11
12 <!-- Login Form -->
13 <form>
14 <input type="text" v-model="data.email" id="login" class="fadeIn second" name="l
15 <input type="password" v-model="data.password" id="password" class="fadeIn third"
16 <input type="button" @click="login" class="fadeIn fourth" value="Log In">
17 </form>
18
19 <!-- Remind Passowrd -->
20 <div id="formFooter">
21 <a class="underlineHover" href="#">Forgot Password? Good! :v</a>
22 </div>
23
24 </div>
25 </div>
26 </div>
27 </template>
28
29 <script lang="ts">
30 import { Component, Vue } from 'vue-property-decorator';
31 import { Action } from 'vuex-class';
32 import authTypes from '../store/types/authTypes';
33 const img = require('@/assets/logo.png');
34 @Component({
35 name: 'Login',
36 data() {
37 return {
38 img,
39 data: {
40 email: '',
41 password: ''
42 }
43 }
44 },
45 components: {
46 },
47 })
48 export default class Login extends Vue {
49 public login() {
50 // console.log(this.$data.data);
51 this.loginUser(this.$data.data);
52 }
53 @Action(`authModule/${authTypes.actions.LOGINUSER}`) loginUser: any;
https://medium.com/@deskevinmendez/agrando-jwt-a-vuejs-204f082391f 5/17
28/6/2020 Agregando JWT a Vuejs - Kevin Mendez - Medium
Aparte de mostrar el html principal, lo que hacemos es generar una acción haciendo
uso de los módulos de vuex, con TypeScript (ya antes explique cómo funcionan los
módulos vuex)
1 <template>
2 <div class="home">
3 <div class="wrapper fadeInDown">
4 <div id="formContent">
5 <!-- Tabs Titles -->
6
7 <!-- Icon -->
8 <div class="fadeIn first">
9 <img :src="img" id="icon" alt="User Icon" />
10 </div>
11
12 <!-- Login Form -->
13 <form>
14 <input type="text" id="name" v-model="data.name" class="fadeIn first" name="name"
15 <input type="text" id="name" v-model="data.email" class="fadeIn first" name="name
16 <input type="password" id="password" v-model="data.password" class="fadeIn third"
17 <input type="password" id="password" v-model="data.password_confirmation" class="
18 <input type="button" @click="registerNow" class="fadeIn fourth" value="Register n
19 </form>
20
21 <!-- Remind Passowrd -->
22 <div id="formFooter">
23 <router-link to="/">Login</router-link> |
24 </div>
25
26 </div>
27 </div>
28 </div>
29 </template>
30
31 <script lang="ts">
32 const img = require('@/assets/logo.png');
33 import { Component, Vue } from 'vue-property-decorator';
34 import axios from 'axios';
35 import authTypes from '../store/types/authTypes';
36 import { Action } from 'vuex-class';
37
38 @Component({
39 name: 'Register',
40 data() {
https://medium.com/@deskevinmendez/agrando-jwt-a-vuejs-204f082391f 6/17
28/6/2020 Agregando JWT a Vuejs - Kevin Mendez - Medium
41 return {
42 img,
43 data : {
44 name: '',
45 email: '',
46 password: '',
47 password_confirmation: ''
48 }
49 }
50 },
51
52 })
53 export default class Home extends Vue {
54 registerNow() {
55 this.registerUser(this.$data.data);
56 }
57 @Action(`authModule/${authTypes.actions.REGISTERUSER}`) registerUser: any;
58 }
ya hemos agregado las vistas para login y register, luego, temporalmente, con código
quemado, mostraremos un home
Ten en cuenta que será temporal, mas adelante, agregaremos contenido dinámico con
datos desde nuestra api
1 <template>
2
3 <!-- Post Content -->
4 <section class="container">
5 <div class="row">
6 <div class="col-lg-12 col-md-10 mx-auto">
7
8 <blogContent/>
9 <blogContent/>
10 <blogContent/>
11
12 </div>
13 </div>
14 </section>
15
16 </template>
17
18 <script lang="ts">
19 import { Component, Vue } from 'vue-property-decorator';
20 import blogContent from '@/components/blog/blog.vue';
21
https://medium.com/@deskevinmendez/agrando-jwt-a-vuejs-204f082391f 7/17
28/6/2020 Agregando JWT a Vuejs - Kevin Mendez - Medium
22 @Component({
23 name: 'Blogs',
24 data() {
25 return {
26 }
27 },
28 components: {
29 blogContent,
30 },
31 })
32 export default class Home extends Vue {}
1 <template>
2 <!-- Navigation -->
3 <nav class="navbar navbar-expand-lg navbar-light fixed-top" id="mainNav">
4 <div class="container">
5 <router-link class="navbar-brand" to="/">Home</router-link>
6 <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="co
7 Menu
8 <i class="fas fa-bars"></i>
9 </button>
10 <div class="collapse navbar-collapse" id="navbarResponsive">
11 <ul class="navbar-nav ml-auto" v-if="userLoged">
12 <li class="nav-item" v-for="item in navLoggedUser" :key="item.name">
13 <router-link class="nav-link" :to="item.to">{{ item.name }}</router-link>
14 </li>
15 </ul>
16 <ul class="navbar-nav ml-auto" v-else>
17 <li class="nav-item" v-for="item in navNotLoggedUser" :key="item.name">
18 <router-link class="nav-link" :to="item.to">{{ item.name }}</router-link>
19 </li>
20 <li class="nav-item">
21 <button class="btn btn-sm btn-light" @click="logout">Logout</button>
22 </li>
23 </ul>
24 </div>
25 </div>
26 </nav>
27 </template>
28
29 <script lang="ts">
https://medium.com/@deskevinmendez/agrando-jwt-a-vuejs-204f082391f 8/17
28/6/2020 Agregando JWT a Vuejs - Kevin Mendez - Medium
30 import { Component, Vue } from 'vue-property-decorator';
31 import { Action } from 'vuex-class';
32 import authTypes from '../store/types/authTypes';
33 @Component({
34 name: 'BlogsNavbar',
35 data() {
36 return {
37 userLoged: false,
38 navLoggedUser: [
39 { name:"Register", to: "/register" },
40 { name:"Login", to: "/login" },
41 ],
42 navNotLoggedUser: [
43 { name:"Home", to: "/" },
44 { name:"Profile", to: "/profile" },
45 { name:"About", to: "/about" },
46 ],
47 }
48 },
49 components: {
50 },
51 })
52 export default class navBar extends Vue {
53 private created() {
54 this.$data.userLoged = !window.localStorage.getItem('_token');
55 }
56 public logout() {
57 this.cerrarSesion();
58 }
59 @Action(`authModule/${authTypes.actions.LOGOUTUSER}`) cerrarSesion: any;
Lo que hace es sencillo, ya que solo toma el token almacenado en localStorage como
booleano, y dependiendo del valor, si es verdadero o falso, muestra un menú
correspondiente de si, el usuario está o no logeado.
Como antes mencioné, esto funciona con typescript, lo hago así, para aprovechar las
características que nos brinda typescript al momento de un tipado para javascript,
aunque ten en cuenta, que no vamos a ser estrictos en este aspecto, ya que solo nos
centramos en como usar jwt desde vue.
Agregamos 3 archivos desde el store de vuex, creamos dentro de la carpeta store/ una
carpeta llamada module, types, e interfaces
https://medium.com/@deskevinmendez/agrando-jwt-a-vuejs-204f082391f 9/17
28/6/2020 Agregando JWT a Vuejs - Kevin Mendez - Medium
dentro de la carpeta module, ira el modulo que se encargara del login, logout, y
obtener el usuario logeado; y la carpeta types, será de donde obtengamos las variables
para usarlas desde cualquier vista, y poder usar las actios, getters y mutations de
authModule. la carpeta, interfaces, será el que contiene la información del State del
modulo.
https://medium.com/@deskevinmendez/agrando-jwt-a-vuejs-204f082391f 10/17
28/6/2020 Agregando JWT a Vuejs - Kevin Mendez - Medium
37 .catch((error: any) => {
38 reject(error)
39 })
40 .finally(() => {
41 return;
42 });
43 });
44
45 },
46 [AuthTypes.actions.LOGOUTUSER]: ({ commit }) => {
47 return new Promise((resolve, reject) => {
48 http
49 .post(`api/auth/logout`)
50 .then((res : any) => {
51 commit(AuthTypes.mutations.SETUSER, {});
52 window.localStorage.removeItem('_token');
53 window.location.reload();
54 resolve(res)
55 })
56 .catch((error: any) => {
57 reject(error)
58 })
59 .finally(() => {
60 return;
61 });
62 });
63 },
64 [AuthTypes.actions.REGISTERUSER]: ({ commit }, data) => {
65 return new Promise((resolve, reject) => {
66 http
67 .post(`api/auth/register`, data)
68 .then((res : any) => {
69 commit(AuthTypes.mutations.SETUSER, res.data.user);
70 window.localStorage.setItem('_token', res.data.access_token);
71 window.location.reload();
72 resolve(res)
73 })
74 .catch((error: any) => {
75 reject(error)
76 })
77 .finally(() => {
78 return;
79 });
80 });
81 }
82 }
83
84 export default {
https://medium.com/@deskevinmendez/agrando-jwt-a-vuejs-204f082391f 11/17
28/6/2020 Agregando JWT a Vuejs - Kevin Mendez - Medium
84 export default {
85 namespaced,
Aquí se hacen todas las peticiones http, aprovechamos las ventajas de las promises de
JS, y hacemos las peticiones al servidor, guardamos los datos, y mostramos en el
frontend.
Pues ese archivo es quien hace la magia para nuestra peticiones axios, ese archivo es
quien almacena y envía nuestro token generado desde nuestro server. (En realidad no
es que lo almacene, sino que lo toma del localStorage, cada vez que hacemos una
nueva petición al server)
El código es el siguiente:
1 - creamos una constante url y una constante http, si podemos ver, dentro de la
constante http
2 - almacenamos la baseURL que nos ayuda a evitar poner la url completa en cada
actions de nuestros módulos; por si aun no comprendes, te lo explico de esta manera:
axios.get(‘api/home’)
Ahora los headers, básicamente es lo mismo, la constante http ya contiene los header
que tenemos que enviar a nuestro server, en este caso, solo el autorizathion requerido
por nuestro server laravel. Pueden haber la cantidad de headers necesarios, los que tú
necesites.
Luego allí mismo, hacemos uso de los interceptores, ¿pero, para qué nos sirve? lo que
los interceptores de axios hace, es capturar errores desde nuestro servidor a nivel
global, a lo que me refiero es que puede haber un error 400, y capturarlo de manera
global, y no necesariamente desde la peticion que lo genera.
Los interceptores son muy útiles cuando queremos hacer una acción como la de
mostrar un loading en cada peticion http. (Lo veremos más adelante)
https://medium.com/@deskevinmendez/agrando-jwt-a-vuejs-204f082391f 13/17
28/6/2020 Agregando JWT a Vuejs - Kevin Mendez - Medium
export default {
mutations: {
SETUSER: ‘SETUSER’,
},
getters: {
GETUSER: ‘GETUSER’,
},
actions: {
LOGINUSER: ‘LOGINUSER’,
LOGOUTUSER: ‘LOGOUTUSER’,
REGISTERUSER: ‘REGISTERUSER’,
};
A lo que nos ayuda este archivo es que podemos hacer uso de estas constantes desde
cualquier lugar de nuestra aplicación, sin restricción de tipo de archivo, es decir,
podemos usarlo tanto dentro de una vista, un componente, o un archivo .ts
Observa que este archivo, contiene el tipo de datos que requerimos en el State del
modulo authModule; es decir, que si queremos usar por ejemplo, userLoged en el
modulo authModule, tenemos que ponerlo en forma de objeto, indicando qué tipo de
https://medium.com/@deskevinmendez/agrando-jwt-a-vuejs-204f082391f 14/17
28/6/2020 Agregando JWT a Vuejs - Kevin Mendez - Medium
datos tiene que ser. Así mismo, vsCode nos ayudará indicando que necesitamos
establecer en el state del modulo el nuevo tipo de datos userLoged.
Por ultimo, necesitamos hacer unas modificaciones en nuestras rutas para lograr
bloquear las rutas que queramos en el frontend, a qué me refiero? es cuando
necesitamos ingresar a nuestra ruta principal, pero ésta está protegida mediante jwt en
el backend; necesitamos que esta ruta, no este disponible para el usuario sin antes
iniciar sesión.
https://medium.com/@deskevinmendez/agrando-jwt-a-vuejs-204f082391f 15/17
28/6/2020 Agregando JWT a Vuejs - Kevin Mendez - Medium
37 }
38 },
39 },
40 {
41 path: '/about',
42 name: 'about',
43 component: () => import(/* webpackChunkName: "about" */ '@/views/About.vue'),
44 meta: { Auth: true, title: 'About' },
45 },
46 {
47 path: '/',
48 name: 'blogs',
49 component: () => import(/* webpackChunkName: "blogs" */ '@/views/Blog.vue'),
50 meta: { Auth: true, title: 'Blogs' },
51 },
52 {
53 path: '/profile',
54 name: 'profile',
55 component: () => import(/* webpackChunkName: "perfil" */ '@/views/Profile.vue'),
56 meta: { Auth: true, title: 'Profile' },
57 }
58 ]
59 })
60
61 router.beforeEach((to, from, next) => {
62 document.title = to.meta.title;
63 if (to.meta.Auth && !window.localStorage.getItem('_token')) {
64 next({ path: '/login' });
65 } else {
66
67 next();
Por si tienes algunas dudas, te recomiendo que eches una leída a la documentación
oficial para router de vue
document.title = to.meta.title;
if (to.meta.Auth && !window.localStorage.getItem(‘_token’)) {
next({ path: ‘/login’ });
} else {
next();
}
});
https://medium.com/@deskevinmendez/agrando-jwt-a-vuejs-204f082391f 16/17
28/6/2020 Agregando JWT a Vuejs - Kevin Mendez - Medium
Este fragmento de código es muy, pero que muy importante a la hora de crear un login
con vue js, porque este interceptor, se ejecuta cada vez que entramos en cualquier URL
establecida en nuestra app, es decir, que si iniciamos en /login, se ejecuta este
fragmento de código, y si entramos en /register o /home o / siempre se ejecuta,
entonces es aquí donde hacemos las verificaciones del token
El if, lo que hace es: verifica si la ruta a la que vamos a entrar, necesita autenticación, y
si necesita tener un token; token que guardamos dentro del localStorage al momento
de iniciar sesión o registrarnos en la aplicación (Puedes guardarlo donde mejor te sea
conveniente)
¿Qué paso con los blogs? pues eso lo dejamos para otro artículo, este ya se nos hizo
un poco extenso.
. . .
DesKevinMendez/vue-jwt-laravel
You can't perform that action at this time. You signed in with another tab or window. You signed out in
another tab or…
github.com
https://medium.com/@deskevinmendez/agrando-jwt-a-vuejs-204f082391f 17/17