Authentication jwt with vuejs

4

I'm a bit confused with authentication using jwt token, I have an application on vuejs + vue-router, I'm not wanting to use vuex until I learn how to do it without it (I do not like to use what I do not understand). So I have my API in NodeJS which grants me a payload with token when the user logs in.

My question is, now I have this token, what do I do with it? I read several articles, said to store in the local storage (vulnerable to XSS), others in the cookie (vulnerable to CSRF), but I do not want to get very safe here, because I have not even worked in any way. What I did was store in local storage when I get the response with the server token as well.

In my main.js it looks like this:

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import axios from 'axios'
import VueAxios from 'vue-axios'

axios.defaults.baseURL = 'http://localhost:3000'
axios.defaults.headers.common['Authorization'] = "Bearer" + localStorage.getItem('jwtToken')

Vue.use(VueAxios, axios)

router.beforeEach((to, from, next) => {
    if (to.meta.requiresAuth) {
        if (**O QUE COLOCO AQUI SEM UTILIZAR O VUEX?**) {
            next() 
        } else {
            next('/')
        }
    } else {
        next()
    }
})

new Vue({
  el: '#app',
  router,
  axios,
  render: h => h(App)
})

Where "to.meta.requiresAuth" means that routes that have the element "meta.requiresAuth = true" will be intercepted by the logic inside the if.

You can see that I do not know what check to do, actually could even check the existence of the token in the local storage, but I believe that just checking the existence or not would be pretty insecure. Since it could say that it has the token being that has not yet been received by the server. But if I do this, the way I thought it would be to send a post to the server and validate the token, if valid, then next () if it is not redirected to the home. But I do not know if that is the proper way to deal with this problem. I'm kind of lost.

    
asked by anonymous 14.03.2018 / 18:39

1 answer

2

In the case, as I said in the comments, I usually save the JWT token in the localStorage. First of all about blocking routes, I usually block any request by creating a interceptor in axios. For this, you can create a js file such as http.js that does this control of requests and intercepts them verifying if the user has a valid token or not, that finally will export an instance of the axios. Follow below:

link

import axios from 'axios'

let api = 'http://localhost:8080/api/'

const http = axios.create({
  baseURL: api
})

http.interceptors.request.use((config) => {
  const token = localStorage.getItem('user-token')

  if (token) {
    config.headers.Authorization = 'Bearer ${token}'
  }

  return config
}, (err) => {
  return Promise.reject(err)
})

http.interceptors.response.use((response) => {
  return response
}, (error) => {
  if (error.response.status === 401) {
    window.location = '#/home'
  }

  return Promise.reject(error)
})

export default http

Basically on each request, it will go through the interceptors.request method and check if it has the token previously, and otherwise it will return an error directly, without actually reaching the backend. The same will occur in the case of the response, and as you said if it is not valid (401), the user is redirected to the home. To use it, it can be imported globally in its main.js or by component.

Speaking about crashing directly into your application's routes, ie passing through your router , I usually do it in two ways:

To lock only one route:

routes: [
    {
      path: '/',
      name: 'home',
      beforeEnter: function (to, from, next) {
        const token = localStorage.getItem('user-token')

        if (!token) {
          next('/login')
        } else {
          next()
        }
      },
      component: require('@/components/Home').default
    },
  ]

In this case he is checking the token before entering the route, and if it does not exist, the user is redirected to the login.

To lock all routes

router.beforeEach((to, from, next) => {
  const token = localStorage.getItem('user-token')

  if (!token) {    
    next('/login')
    return;
  }

  next();
});

Same operation, however it will check on all routes, and if the token does not exist, it will redirect to the login. In this case must have a constant routes with all its routes inside.

const router = new Router({
  routes: []
});

I hope I have helped.

    
15.03.2018 / 01:08