Vue router is unable to verify the user's authentication

I have certain app routes that are supposed to be restricted to admins only. I've added requiresAdmin: true, to the meta of those routes, but for some reason it doesn't prevent other users from accessing them.

Code

Note: I've included comments in the code for better understanding.

const router = new VueRouter({
    mode: "history",
    routes: [
        // ADMIN ROUTES
        {
            path: '/export',
            name: 'ExportXML',
            component: ExportXML,
            meta: {
                requiresAuth: true,
                requiresAdmin: true,  // only admins can see this page
                layout: 'admin',
                name: 'Export XML',
            }
        },
    ]
});

router.beforeEach((to, from, next) => {
    if (to.matched.some(record => record.meta.requiresAuth)) {
        if (!store.getters.isLoggedIn) {
            next({
                name: 'login'
            })
        } else {
            next()
        }
    }
    if (to.matched.some(record => record.meta.requiresAdmin)) {
        // first make sure getter can get logged user data
        if (store.getters.loggedUser && !store.getters.loggedUser === undefined) {
            // then check if loged user "type" is admin (any other possebilities are denied)
            if (!store.getters.loggedUser.type === 'admin' || store.getters.loggedUser.type === '' || store.getters.loggedUser.type === null || store.getters.loggedUser.type === undefined || store.getters.loggedUser.type === 'worker') {
                next({
                    name: 'dashboard'
                })
            } else {
                next()
            }
        }
    }
    else {
        next()
    }
});


router.afterEach((to, from) => {
    Vue.nextTick(() => {
        document.title = to.pageTitle || 'Testing Site';
    });
});

export default router;

Can anyone explain why a user with the type of worker is still able to access the exports page, even though it is meant to be restricted to admins only?

Answer №1

The problem lies here

if (to.matched.some(record => record.meta.requiresAuth)) {
  if (!store.getters.isLoggedIn) {
    next({
      name: 'login'
    })
  } else {
    next() // 👈 right at this point
  }
}

Once it's confirmed that the user is logged in, no further checks are made.

You should integrate the additional if block for admin verification into the mentioned else block, replacing the existing next(). Alternatively, you could streamline this process by using return to exit when necessary.

if (to.matched.some(({ meta }) => meta.requiresAuth) && !store.getters.isLoggedIn) {
  return next({ name: 'login' }) // not logged in, redirect to login
}
if (to.matched.some(({ meta }) => meta.requiresAdmin)
    && store.getters.loggedUser.type !== 'admin') {
  return next({ name: 'dashboard' }) // not an admin, redirect to dashboard
}
next() // otherwise, everything is okay

https://codesandbox.io/s/modest-meninsky-w3u2z?fontsize=14&hidenavigation=1&theme=dark

Answer №2

please review my comments within the code snippet

if (to.matched.some(record => record.meta.requiresAuth)) {
    if (!store.getters.isLoggedIn) { // <== issue with this condition
        next({
            name: 'login'
        })
    } else {
        next().  //  this line will always run for any logged-in user, allowing access to all URLs in your application
    }
}

consider the following solution

if (to.matched.some(record => record.meta.requiresAuth)) {
    if (!store.getters.isLoggedIn) { 
        next({
            name: 'login'
        })
    } else {
        
        // verify that the logged-in user's "type" is admin (other possibilities are restricted)
        if (!store.getters.loggedUser.type === 'admin' || store.getters.loggedUser.type === '' || store.getters.loggedUser.type === null || store.getters.loggedUser.type === undefined || store.getters.loggedUser.type === 'worker') {
            next({
                name: 'dashboard'
            })
        } else {
            next()
        }
    }
    
}
else {
  next()
}

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

The Magic of jQuery Cross Site Fetch

It seems like this should be simple, but I am having trouble figuring it out... I'm using jQuery to fetch a remote page from a different server, grab the HTML content, and then insert that content into a hidden DIV. However, when I try to do this wit ...

How can I designate the file name when using Ajax to export in Excel formatting?

Can you help me with the code to set a specific filename for downloading an Excel file? if(comp_id != "Select Company") { $.ajax({ url: 'includes/export.php', data: { action: 'compreport', 'comp':comp_i ...

JavaScript error: You are trying to use Array.find() in Redux, but it

I am currently developing a react native application and I am using basic redux for managing the state, although I am a complete beginner to this. In a specific issue, I am facing an issue while fetching data from my redux store in the edit screen where th ...

Adding a clickable button to execute code within a LeafletJS marker!

I'm currently experimenting with adding a button inside a pointer that will log a message to the console. This is simply a test to see if I can execute a method on the marker, but so far I haven't been able to display any text. const marker = L.m ...

Promise chain failure in express

I've developed an express.js server for managing REST API requests and extracting data from a MongoDB database. However, I'm encountering an issue with the promise chain when I send a GET request to a specific endpoint ("localhost:8081/api/getUse ...

Tips for preventing Chrome from masking the background image and color on an autofill input

Google Chrome Browser has caused the background-color and background-image effects to be removed from the Username and Password input fields. Before autocomplete https://i.stack.imgur.com/Ww7Hg.png After autocomplete https://i.stack.imgur.com/hbG2C.png ...

Creating a dynamic b-table in Vue.js with editable fields and two-way data binding

I am attempting to create a dynamic b-table with editable fields that have two-way databinding. My goal is to avoid any hardcoded values. Currently, I have the following setup: <b-table striped hover :items="filtered"> <template v-slot:cell( ...

Obtain the date in ISO format without subtracting the timezone offset

I need to obtain a Date string without the timezone being added or subtracted. Currently, when I set my OS timezone to GMT +13 and create a new Date() object, the toISOString() method subtracts one day. For example, today is 11/02. If I adjust my OS time ...

IE is failing to trigger jAlert function

When I validate a text box by pressing the enter key on my keyboard, the validation works fine but the JAlert doesn't show up. However, when I call the same function on a button click, the alert shows in IE. I am quite confused by this behavior and wo ...

Tips for displaying an object's key/value pairs on a webpage

I'm attempting to use jQuery's .each() function to write the key/value pairs from an object onto the page. However, I am only able to get it to display the last key/value pair. If you want to check out a code example and demo, here is the link: ...

Unable to retrieve basic profile data from LinkedIn Members using their email ID unless they are signed in

I am struggling to retrieve the basic profile details of Linkedin Members using their email ID. Despite my efforts, I haven't been able to find relevant information in the documentation. My attempt involved creating an app, initializing the JavaScrip ...

"JavaScript/jQuery: The pattern in the text does not align with the string

I am currently working on validating a text field with the specific data pattern of "I-MH-ABCD-ABC-1222". Below is the regular expression I have implemented, but unfortunately it is not functioning as intended. var router_added_sap = "I-MH-ABCD-ABC-1222" ...

Can Hapi-Joi validate a payload consisting of either an Array of objects or a plain Javascript object?

How can I create a schema to validate payloads for a post call that accepts either a single JS object or an array of objects to be saved in the database? JS object { label: 'label', key: 'key', help_text: 'text' } ...

Adding data to a multidimensional array in JavaScript

I am in need of creating a multidimensional JavaScript array dynamically, following this specific structure: array_answers[0][1]:"yes" array_answers[1][2]:"no" array_answers[2][2-subquestion]:"text input" array_answers[3][8]:"yes" array_answers[4] ...

When the parent div contains at least four divs, show the scroll arrow containers

In my code, there is a parent div that holds multiple child divs. If the number of child divs within the parent div exceeds 4, I want to show the scroll arrow containers. If it's less than 4, then those arrow containers should not be displayed. The ...

Using Angular's filter service within a controller

Just starting out so please be kind!! Encountering an issue with Angular 1.3 while using a Stateful Filter within a controller. In brief, when utilizing the $filter('custom')(data) method instead of the {{ data | custom }} method - and the cust ...

Issues arise when trying to use Prettier and ESlint in conjunction with one another

It appears that prettier is not formatting the code as desired. Here is my current ESLint configuration: "eslintConfig": { "root": true, "env": { "node": true }, "extends": [ &q ...

Is there a way to display an XML listing recursively similar to the functionality of an ASP:MENU in the past?

I have been working on converting a previous asp:menu item to JavaScript. Here is the JavaScript code I have come up with: function GetMainMenu() { var html = ''; var finalHTML = ''; finalHTML += '<d ...

Navigating through the content of slots within recurring slots in a subcomponent in Vue.js

I am encountering an issue with a child component, where each row in an object is rendered inside a div with a specific slot. I need to pass data from the parent for each of these elements. I've been attempting to iterate through every element of the ...

What assistance is available for building a JavaScript package that integrates and utilizes all necessary dependencies?

I am looking for a solution to include a third-party library in a JavaScript file that will be downloaded to our project only when we visit a specific page. This library is installed with npm and I want it to be part of the js package without includi ...