Ensuring safe access to a Vue.js single-page application

After following numerous Vue.js tutorials, I have encountered a dilemma. Imagine I am constructing a single-page application where a user can log in and access data through a RESTful API.

The initial step involves sending login credentials (username and password) to the API to receive an authentication token. This token is then stored in Vuex as well as local storage or cookies to maintain the user's logged-in status even after a page refresh.

All subsequent API requests are authenticated using this token.

My routes are configured as follows:

const routes = [
    {
        path: '/dashboard', name: 'dashboard', component: Dashboard, meta: { requiresAuth: true }
    },
    {
        path: '/login', name: 'Login', component: Login,
    },
]

I utilize a route guard to prevent non-logged-in users from accessing the /dashboard page:

router.beforeEach((to, from, next) => {
    if (to.matched.some(record => record.meta.requiresAuth)) {
        if (!store.getters.loggedIn) {
            next({ path: "/login" })
        } else {
            next();
        }
    } else {
        next();
    }
})

However, my concern lies with the implementation of the loggedIn getter in the Vuex store:

const getters = {
    loggedIn(state) {
         return state.token !== null;
    }
};

Although everything appears to be functioning correctly, there is a security vulnerability. By manipulating the access_token value in local storage using developer tools, one could gain unauthorized access to the /dashboard page upon refreshing.

This leads me to question how to prevent this scenario. One potential solution is to split the application into two pages - a login page for authentication performed server-side via sessions, and a separate SPA accessible only to authenticated users.

Alternatively, is there a standard method for addressing this issue within a SPA environment?

Answer №1

As mentioned in the feedback, I suggest implementing a function called checkLogin() as follows:

checkLogin() {
      axios
        .get('/webapi/check')
        .then(() => {})
        .catch(err => {
          if (err.response.status === 401) {
            // Use a mutation to change the "loggedIn" state
            this.$store.commit('loggedIn', false)
            if (this.$route.path !== '/login') {
              this.$router.push('/login')
            }
          }
        })
    }

You can then utilize your routeGuard to invoke this function whenever there is any routing change.

Additionally, ensure that your backend does not allow valid responses without the token.


UPDATE:

Make sure to have a state for 'loggedIn' and perform a mutation to update this state based on the backend response.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue with ng-selected not functioning properly

I am facing an issue where the ng-selected is assigned as true but the option is not being selected. The following is my controller code: .controller("PendingInvoiceCtrl", function($scope, $location, safeApply, dataService) { var userData = dataServi ...

How can permissions for video and audio be configured in Next.js?

When the button is clicked, I want to set permissions. This is how I'd like the scenario to play out: first, the method works initially and allows permission when the button is pressed. Here is my code: <button onClick={requestPermission} classN ...

Showing a notification message in AngularJS when an object is empty within a repeating element

Currently, I am utilizing AngularJS along with a repeater to cycle through some search results while also implementing a filter for searching purposes. There are two specific scenarios that I need to address effectively and I am eagerly seeking the most " ...

Encountered an issue with parsing the source map while working on my personal computer

WARNING: failed to parse source map from specified file location due to a missing file or directory. I encountered this error message while trying to launch my React application, and I'm unsure of the cause. ...

The Angular Material md-menu element stubbornly refuses to close when clicked outside, especially if the target element has a fixed position and

I currently have a <md-menu> element implemented in my webpage. By default, the menu will close if clicked anywhere on the page. However, I have noticed that when clicking inside a fixed element with a specified z-index, the menu does not close. < ...

Having issues with my jQuery getJSON request. It's returning an empty response even though

I have been struggling to find a solution to this particular issue with no luck... Here is the jQuery getJSON request that I am working on: $.getJSON("http://localhost:8080/context/json/removeEntity.html", { contentId : 1, entIndex : entityIndex ...

I'm having trouble with my AJAX Update Panel. Can someone please help me figure out what I'm doing wrong?

--------------Handling Gridviews DataBound Event ----------------- protected void grdShowCallingList_DataBound(object sender, EventArgs e) { if (grdShowCallingList.Rows.Count > 0) { foreach (GridViewRow row in grdShowCallingList.Rows) ...

Can transitions be applied to links in this manner?

Having an issue with ajax requests, I am currently resorting to using JavaScript linking. This is how I normally link: window.location.href = ('file:///android_asset/www/custom/kontakty.html'); I am curious if it's possible to add a transi ...

Equivalent of ResolveUrl for loading scripts without the need for server technology

I am in the process of converting an ASP.NET web page into a plain HTML web page. Most of the work is done, however, I am having trouble replacing the ASP.NET Page.ResolveUrl function when setting a reference to a javascript file: <script src="<%= ...

Exploring Three.js on Cordova with WebGL

I am working on developing a mobile app using Three.js on Cordova. While the app runs smoothly on a PC browser, it encounters an issue when trying to create the WebGL context on a Samsung Note 3 device. The specific error message is: THREE.WebGLRenderer ...

Unlock the App Store instead of iTunes Store using react-native-version-check

I am currently using react-native-version-check to trigger the opening of the app store or play store if an update is available. However, on iOS it redirects to the iTunes store instead of the desired AppStore location. Below is the code in question: ...

What causes the Error: ENOENT open error to occur when attempting to render a doT.js view?

My first experience with doT.js led me to create a basic server setup: 'use strict'; var express = require('express'); var app = express(); var doT = require('express-dot'); var pub = __dirname+'/public'; var vws ...

Resolving issues with JavaScript caused by Polymer updates

I am a novice when it comes to working with Polymer. From what I have gathered, there seems to be compatibility issues with Mozilla and Safari. After researching on StackOverflow, I found that adding addEventListener('WebComponentsReady', funct ...

Having trouble with V-model while using CKEditor in vue.js sourced from the original?

Whenever I start a new vue project with CKEditor from source, I encounter an issue where the V-model for editor components does not function as expected. The ClassicEditor is unable to edit and update data properly. Is this a bug? vue.config.js const path ...

Revamp the table layout for mobile with a unified markup structure

I want to customize the display of my bootstrap table for mobile view. Each row entry should be shown in a separate box or card, similar to the following examples: First: Mark Last : Otto Handle: @mdo Second card- First:Jacob Last:Thornton Handle:@fat Is ...

Obtain offspring from a parent element using jQuery

$(document).ready(function() { $.ajax({ type: "POST", url: 'some/url', data: { 'name':'myname' }, success: function (result) { var result = ["st ...

The property number will have no effect on the time

Currently, I am in the process of developing an audio player that includes essential functions such as backward, play, and forward buttons. Strangely enough, the backward function operates perfectly fine, but the forward button is not functioning properly ...

Tips for creating a Discord bot that can respond to inquiries with varying responses

Lately, I've been working on a Discord bot that selects a random response from an array of replies. My goal is for it to display an error message if the question is unknown or if no arguments are provided after the command. I currently have some code ...

The HTMLInputElemet type does not include a Property Rows

Hey there, I'm just starting to dive into Angular and TypeScript. My current challenge is figuring out how to check if a table is empty or not so that I can show or hide a specific div accordingly. I've attempted the following: var rows = docume ...

Creating a new JSON by extracting a specific branch or node from an existing JSON data

I have a Nuki Smartlock and when I make two API calls to the Nuki Bridge, I receive JSON responses. I want to apply the same logic to both responses: When requesting for current states, the JSON looks like this: [{ "deviceType": 0, "nuk ...