I'm working on an SPA with Vue.js and vue-router and I'm now dealing with authorization/authentication using JWT. I have the back end (API endpoint) sorted out, such that it will issue a token in response to a login and check for the requisite header on subsequent requests. I now want to implement the client (Vue.js) side.
As I understand it, fundamentally what I need to do is to require authentication for all routes apart from '/' and '/login'. If authentication is present then I submit the token (which is stored in localStorage after a successful login) in an Authorization header. If it fails to validate successfully on the server, then the user will be redirected to '/login' as a result of the error response.
So, I have a couple of questions about what I need to do to implement this:
How do I best submit a header with every request, apart from to the login endpoint? I know with JQuery, which I'm using for AJAX, I can configure a global 'ajaxSetup' which will cause the header to be submitted with each request, but how can I specify exceptions? It's cumbersome to individually add the header to each API endpoint request.
Similarly, how to I set up an authentication pre-check which applies to all routes apart from the 2 mentioned ('/' and '/login')?
Given that I'm using the presence or otherwise of apparently valid authentication (apparently because it still has to be validated on the API endpoint) to determine whether or not to show certain menu items, etc., is it feasible to make this more granular and show different things for different permission levels, as determined by the 'scope' field in the token payload? Clearly the simplest way of dealing with a JWT token is purely to determine whether it is present or not, so no parsing of content is required at the client end. But given that JWT does allow meaningful content, is it a bad idea to try to make use of that meaning on the client side as well as server? Obviously this becomes less practical if the token is itself encrypted, so my idea would be to use unencrypted tokens (and ensure nothing of any consequence is exposed in the payload).
All source code for the Vue + Vuex JWT authentication app is located in the /src folder. Inside the src folder there is a folder per feature (app, home, login) and a few folders for non-feature code that can be shared across different parts of the app (_store, _services, _helpers).
We started with the entire backend setup, built our app, and then worked on the client-side of the application. JWT offers a purely stateless authentication mechanism because the user state is never saved in the server memory or database.
JWTs are commonly used for either authentication or to safely transmit information across different parties. Once a user has logged into an app, a JWT is created on the server and returned back to the calling client, which is a common flow for JWT-based authentication systems.
There are three important parts of a JWT: Header, Payload, Signature. Together they are combined to a standard structure: header.payload.signature. The Client typically attaches JWT in x-access-token header: It will be a full stack, with Node.js Express for back-end and Vue.js for front-end. The access is verified by JWT Authentication.
You can do global headers, and when the user is authenticated, add to the global headers the token like this example , I'm using Axios.
axios.defaults.headers.common['Authorization'] = "Bearer"+ authtoken.token
For checking the authentication of the user or to manage parts of your website, simply add global variable, and when the user is authenticated set the variable to true. Alternatively, use Vuex and it will be easy and the element you want to hide or to show to the user simply add v-if to the element like (example using Vuex)
<div v-if="this.$store.state.authenticated"> Hide Element from Guests </div>
And for the route, in your routes add meta field to indicate the path is requires authentication
{
path: '/dashboard',
component: DashboardPage,
name: 'Dashboard',
meta: {requiresAuth: true} // Meta Field , you can name it
}
In your Vue Router configuration add navigating guards that check the presence of the meta field, and if true check the if the user is authenticated
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
if(to.meta.requiresAuth) { // check the meta field
if(store.state.Authenticated) { // check if the user is authenticated
next() // the next method allow the user to continue to the router
}
else {
next('/') // Redirect the user to the main page
}
}
else {
next()
}
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With