Thursday, 18 January, 2018 UTC


Summary

Vue authentication management Introduction
Whenever you start to get serious with a project, you will most likely face the issues of how to handle client-side token-based authentication.
You will have to answer these questions:
  • How do I store my user’s token?
  • How do I redirect the user after authentication actions ( Login/ Logout )?
  • How do I prevent route access to authenticated and unauthenticated users?
This article will walk you through these questions and try to illustrate with clear code and good practices in mind.
However, keep in mind that all project have different authenticated behavior. Projects can be just a loading screen until you are logged in (gmail) or still being able to see the application but doesn’t have access to everything features (amazon), so you will probably have to adjust what i will describe here.
 
Before we start
I have made this repo if you want to run some code.
We use vuex as the global state library. Vuex is especially suited for auth management since it’s application scoped. You don’t want to use vuex, no worries we also give some code example without vuex
We also use the axios library for the ajax calls.
Finally, this article will not show how to implement the backend side of the authentication process. We will only focus on the client side.
Login
Let’s start with a simple login form:
View the code on Gist.
When the user has filled the inputs and clicked Login, we execute the login method.
View the code on Gist.
Here is the first important bit of this code snippet.
  • Vuex actions returning promises.
this.$store.dispatch(AUTH_REQUEST, { username, password }).then(() => {
Did you know? You can also treat action dispatch as promises ! Now we can react on successful login from the component. Allowing us to redirect accordingly.
The same code without vuex:
View the code on Gist.
Vuex Auth Module
Let’s now look at this auth module:
First let’s initialize the state.
We will have the token field (using localstorage stored token if present) and a status field, representing the status of the API call (loading, success or error).
View the code on Gist.
Some useful getters:
View the code on Gist.
Now the action:
View the code on Gist.
And the mutation:
View the code on Gist.
A fairly simple API call from a module. The important bits are:
  • Token state being initialized by its local storage value, if possible.
  • The Authentication request action returns a Promise, useful for redirect when successful login.
  • Good practice: pass the login credentials in the request body, not in the URL. The reason behind it is that servers might log URLs, so you don’t have to worry about credential leaks through logs.
Logout
Since we are at it, let’s implement our logout logic in modules/auth.js:
View the code on Gist.
When clicking on the logout button in one of you components responsible for logout:
View the code on Gist.
In this case loging out for us means clearing out the user’s token and redirect him. If you need to perform other vuex state changes, listen for this AUTH_LOGOUT action and commit.
Try to keep it simple, as few actions as possible to Logout/Login.
If you start to create one login/logout action per authentication type that you have, you will have an headache maintaining them.
Use the token
Now that we have managed to retrieve the token and store it, let’s use it.
The following example is using Axios and its default headers.
in modules/auth.js
View the code on Gist.
Now after login, all the Axios calls have the authorization header set to your token. All your API calls are authentified ! And when logging out, we delete the authorization header.
Auto authentication
Right now if we refresh the app, we do have the state correctly set to the previous token, however the authorization Axios header isn’t set. Let’s fix it!
In your main.js:
View the code on Gist.
Now your API calls are authentified when refreshing your app after login!
Authenticated routes
Now you probably want to restrict access to your routes depending on whether they are authenticated or not.
In this case we want authentified users only to reach /account.
And unauthenticated users should only be able to reach /login and /.
 
View the code on Gist.
Here we use naviguation guards, they allow us to put conditions on routes access that we use to our advantage in conjunction with the vuex store.
 
Note 1: If you do not wish to use Vuex, you can still check for token presence in the localstorage rather than looking at the store getters
Note 2: Ed @posva, maintainer of vue-router also advice the usage of meta attributes, check it out
Handling the unauthorized case scenario
…but wait, what if the token is expired, what if the user is unauthorized?
No worries here.
Using Axios, you can intercept all responses, and especially the error response. Just check for all unauthorized responses (HTTP 401) and if so, dispatch a logout action.
In your App.vue
View the code on Gist.
And we are good to go !
Conclusion
What have we achieved here ?
  • Isolated authentication logic from the app and other libs.
  • We won’t need to explicitly pass tokens to every api call.
  • Handle all unauthenticated api calls
  • We have auto authentication
  • We have restricted routes access
What have we learned ?
  • Separation of concerns
  • Avoid side effects
  • Action dispatch can return promises
 
This should give you a pretty solid starting point for handling all your api calls in your app.
Hopefully this will be helpful fo your futur projects!
The post Authentication Best Practices for Vue appeared first on Sqreen Blog | Modern Application Security.