Page to route 404 with login - vue.js

My problem is when I started using a router.beforeEach() he won't go to the page of 404 when I typ a not existing link. He just go to page with the defaukt layout I use. I use router.beforeEach() for checking if a user is logged in or not. Is there something missing, or is there something wrong?
This is my router.js
let router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'login',
component: () => import('./views/Login.vue'),
meta: {
layout: "empty"
},
},
{
path: '/home',
name: 'home',
component: () => import('./views/Home.vue'),
meta: {
requiresAuth: true
}
},
{
path: '/404',
name: '404',
component: () => import('./views/404.vue'),
meta: {
layout: "empty"
},
},
{
path: '*',
redirect: '/404'
},
{
path: '/*',
redirect: '/404'
}
]
});
router.beforeEach((to, from, next) => {
const isLoggedIn = JSON.parse(localStorage.getItem('UH'));
console.log(isLoggedIn);
const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
if (isLoggedIn === null){
if (requiresAuth && !isLoggedIn.user) {
next('/');
} else {
next();
}
} else {
next();
}
});

If I understand well your problem, when a user type something wrong in the url and is not logged in, this user is redirected to '/' instead of 404.
It's because the beforeEach hook is used before your route redirect {path: '*', redirect: '/404'} and your condition to redirect an user not logged in if the page requiresAuth is true.
To solve the problem, add an other condition like this:
if (isLoggedIn === null){
if (requiresAuth && !isLoggedIn.user) {
if (!to.matched.length) {
next('/404');
} else {
next('/');
}
} else {
next();
}
} else {
next();
}

Related

the redirect url contains the absolute and relative path while redirection from route.beforeach

In my vue js application, I have a vue-router setup as follows: In route.beforeach I am checking whether the application is already authenticated or not, base upon that I had to redirect to login page.
let router = new VueRouter({
routes: routes,
mode: "history",
scrollBehavior: () => ({ x: 0, y: 0 }),
});
Vue.use(VueGtag, {
config: { id: process.env.VUE_GTAG }
}, router);
export default router;
router.beforeEach((to, from, next) =>
{
if (to.matched.some(record => record.meta.requiresAuth) && !(authService.myMsal.getAllAccounts().length > 0))
{
next({
name: "page-login",
query: {
redirect: to.fullPath
}
});
} else
{
next()
}
});
and in route.js it is setup as:
const routes = [
{
path: '/login',
name: 'page-login',
component: Login
},
{
path: '/',
component: () => import('layouts/MyLayout.vue'),
meta: {
requiresAuth: true,
},
children: [
{
name: 'home',
path: '',
component: () => import('components/Home.vue'),
meta: {
requiresAuth: true,
},
},
],
},
]
In router.beforeEach when the application has to redirect to page-login, it is redirected with a full path as: http://localhost:8080/http:/localhost:8080/login?redirect=%2F
it should have to be redirected to http:/localhost:8080/login, what is causing this behavior?

Quasar \ VueJS 3 infinite route looping/

I got some routes in my routes.js file
path: '/main',
component: () => import('layouts/MainLayout.vue'),
beforeEnter: (to, from, next) => {
console.log(store.authState.auth.role)
if (Number(store.authState.auth.role) === 4) {
next({ path: '/main/admin' })
} else {
next()
}
},
children: [
{
path: '',
component: () => import('pages/Main.vue'),
meta: { requiresAuth: true }
},
{
path: 'user',
component: () => import('pages/User.vue'),
meta: { requiresAuth: true }
},
{
path: 'admin',
component: () => import('pages/Admin.vue'),
meta: { requiresAuth: true }
}
]
}
and i have some code in index.js router file:
Router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth) && !store.authState.auth.state) {
next({ path: '/' })
} else {
next()
}
})
The main idea was - if user not login - redirect to root, if user login and go to /main route, depends on his role router must redirect him to specific route.
But in fact - i got infinite loop for role === 4 (example) - what i do wrong? Thank you
Your beforeEnter navigation guard is being applied to the entire /main route, and /main/admin is nested within that route. That means that the guard is being called on /main/admin itself, so any admin user who requests that page (or is redirected to it) will be redirected from that page to itself.
Based on your description, you probably want to apply your navigation guard to just the exact /main route and not its entire tree. You could then go on to redirect to next({ path: '/main/user' }) instead of simply accepting the current path with next() at the end of the guard. If that's what you want, then you don't actually need a component there at all, since the route will never be rendered. Here's how that would look:
path: '/main',
component: () => import('layouts/MainLayout.vue'),
children: [
{
path: '',
component: () => import('pages/Main.vue'), // FIXME: not needed?
meta: { requiresAuth: true },
beforeEnter: (to, from, next) => {
if (Number(store.authState.auth.role) === 4) {
next({ path: '/main/admin' })
} else {
next({ path: '/main/user' })
}
},
},
{
path: 'user',
component: () => import('pages/User.vue'),
meta: { requiresAuth: true }
},
{
path: 'admin',
component: () => import('pages/Admin.vue'),
meta: { requiresAuth: true }
}
]
}

Why does the router link not work the first time?

I have a grpc application, there is authorization. When you start a project, you must be logged in. I decided to add under the login button if you are not registered. But the router does not work. Only at the entrance, go to the registration page. Please help to understand what is the mistake? Why is seemingly blocked?
routes.js
const routes = [
{
path: "/",
component: () => import("layouts/MainLayout"),
children: [
{
path: "",
component: () => import("pages/Index"),
meta: { requireAuth: true }
},
{
path: "/logs",
component: () => import("pages/Logs"),
meta: { requireAuth: true, admin: true }
}
]
},
{
path: "/",
component: () => import("layouts/AuthLayout"),
children: [
{
path: "/welcome",
component: () => import("pages/Auth"),
meta: { guest: true }
},
{
path: "/register",
component: () => import("pages/Register"),
meta: { guest: true }
}
]
}
];
I tried many things, like in Auth.vue:
<q-item to='/register'>Sign Up</q-item>
<router-link tag="a" :to="{path:'/register'}" replace>Go</router-link>
<span #click="callSomeFunc()">Register</span>
...
methods: {
callSomeFunc() {
this.$router.push({ path: "/register" });
}
My router-view in App.vue
for more information github repo
You have duplicate routes in your config - the path / is used on 2 routes. You should fix this.
To prevent unauthorized users to see your protected pages you can add a global navigation guard to your router through the beforeEach hook:
import VueRouter from 'vue-router';
const routes = [
{
path: "/",
component: () => import("layouts/MainLayout"),
meta: { requireAuth: true },
children: [
{
path: "",
component: () => import("pages/Index"),
},
{
path: "logs",
component: () => import("pages/Logs"),
meta: { admin: true }
}
]
},
{
path: "/login",
component: () => import("layouts/AuthLayout"),
children: [
{
path: "",
component: () => import("pages/Auth"),
},
{
path: "/register",
component: () => import("pages/Register"),
}
]
}
];
const router = new VueRouter({
routes
});
router.beforeEach((to, from, next) =>
{
if (to.matched.some(route => route.meta.requireAuth))
{
if (userNotLogged) next('/login');
else next();
}
else next();
});
export default router;
You may also consider reading a more verbose tutorial, e.g. https://www.digitalocean.com/community/tutorials/how-to-set-up-vue-js-authentication-and-route-handling-using-vue-router

vue-router : Navigation not routing to correct path

I am using vuex and vue-router. I have a client's zone, when you try to loggin, you should go to the profil. But it's not happend.
routes: [
{
path: "/area-do-cliente",
name: "customerZone",
redirect: "/area-do-cliente/profile",
component: () =>
import(
/* webpackChunkName: "ClientZone" */ "#/scenes/ClientZone/views/ClientZone.vue"
),
children: [
{
path: "login",
name: "login",
component: () => import("#/scenes/ClientZone/components/LogIn.vue"),
props: true,
meta: { clientZoneLogin: true }
},
{
path: "profile",
name: "profile",
component: () => import("#/scenes/ClientZone/components/Profile.vue"),
meta: { clientZoneAuthRequired: true, clientZoneLogin: true },
props: true
},
]
}
]
router.beforeEach((to, from, next) => {
if (to.matched.some(_to => _to.meta.clientZoneLogin))
if (store.getters.personData.status == "1") {
console.log("01");
router({ name: "profile" });
} else {
console.log("2");
next();
}
} else {
console.log("3");
next();
}
}
});
So I still have in console => 2. It is mean that I pass the first condition, but I shouldnt. I have status 1, and the response of this data is when you click the login button (there is a event).
methods: {
doLogin: function() {
this.error = "";
let loginData = {
login: this.login,
password: this.password
};
this.isLoading = true;
this.errorMessage = "";
co.postLogin(loginData)
.then(data => {
this.$store.commit("personData", data.data); // here I push data to store
)}
}
}
Any ideas where is mistake?

How to properly use the meta props on vue router?

I'm trying to handle route middleware of the children route, but I got this error
Uncaught TypeError: route.children.some is not a function
The documentation are only shows the example for a single route but in this case, I have a children route that needs to be restricted.
Please take a look at my router configuration:
import Vue from 'vue'
import Router from 'vue-router'
import store from './store/index'
import Home from './views/home/Index.vue'
Vue.use(Router)
let router = new Router({
mode: 'history',
base: process.env.VUE_APP_BASE_URL,
linkActiveClass: 'is-active',
linkExactActiveClass: 'is-exact-active',
routes: [{
path: '/',
name: 'home',
component: Home,
meta: {
requiresAuth: true
}
},
{
path: '/login',
name: 'login',
// route level code-splitting
// this generates a separate chunk (login.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import('./views/auth/Login.vue'),
meta: {
requiresGuest: true
}
},
{
path: '/register',
name: 'register',
component: () => import('./views/auth/Register.vue'),
meta: {
requiresGuest: true
}
},
{
path: '/forgot-password',
name: 'forgot-password',
component: () => import('./views/auth/extras/ForgotPassword.vue'),
meta: {
requiresGuest: true
}
},
{
path: '/database',
name: 'database',
component: () => import('./views/database/Index.vue'),
meta: {
requiresAuth: true
}
},
{
path: '/third-parties',
name: 'third-parties',
component: () => import('./views/third-parties/Index.vue'),
meta: {
requiresAuth: true
}
},
{
path: '/editor',
name: 'editor',
meta: {
requiresAuth: true,
requiresAdmin: true,
requiresEditor: true,
},
children: {
path: ':appSlug/layout-editor/:pageSlug',
name: 'layout-editor',
component: () => import('./views/editor/Index.vue'),
}
},
]
})
router.beforeEach((to, from, next) => {
const isLoggedIn = store.getters['auth/isLoggedIn'];
// Role getters
const isAdmin = (store.getters['auth/isAdmin'] == 'admin') || (store.getters['auth/isAdmin'] == 'super-admin');
const isEditor = store.getters['auth/isEditor'] == 'editor';
// Redirect to the login page if the user is not logged in
// and the route meta record is requires auth
if (to.matched.some(record => record.meta.requiresAuth) && !isLoggedIn) {
next('/login')
}
// Redirect to the homepage page if the user is logged in
// and the route meta record is requires guest
if (to.matched.some(record => record.meta.requiresGuest) && isLoggedIn) {
next('/')
}
// Redirect to the preview page if the user is logged in
// but has no role assigned or the role is user
if (to.matched.some(record => (
record.meta.requiresAuth &&
record.meta.requiresAdmin &&
record.meta.requiresEditor)) && !isAdmin && !isEditor) {
next('/preview')
}
// Pass any access if not match two conditions above
next()
})
export default router
Could somebody please explain it? Why I getting this error and how to fix it?
Thanks in advance.
I just found the answer, kinda silly tho.. I forgot to put square brackets on the children props. Now it's working as I expected.
fix:
{
path: '/editor',
name: 'editor',
meta: {
requiresAuth: true,
requiresAdmin: true,
requiresEditor: true,
},
children: [{
path: ':appSlug/layout-editor/:pageSlug',
name: 'layout-editor',
component: () => import('./views/editor/Index.vue'),
}]
},