exclude a path from vuex-oidc in vue router - vue.js

I'm using below code to create my vue app routes and vuex-oidc vuexOidcCreateRouterMiddleware to protect them.
My routes are not only in this file. I'm using axios in App.vue to get other routes from an api endpoint and add them to routes using this.$router.addRoute()
When these extra routes are loaded beforeEach applied vuex-oidc to all routes.
Up to this point all works perfectly.
My problem is
I need to exclude "Welcome" route so vuex-oidc will not be applied to it. So it will be accessible to all visitors not only logged-in users.
How can i edit following line to exclude Welcome route?
router.beforeEach(vuexOidcCreateRouterMiddleware(store, 'oidcStore'))
or any other solution.
Thanks
import { createRouter, createWebHistory } from 'vue-router'
import { vuexOidcCreateRouterMiddleware } from 'vuex-oidc'
import store from '#/store'
const routes = [
{
path: process.env.BASE_URL + 'oidc-callback',
name: 'OidcCallback',
component: () => import(/* webpackChunkName: "OidcCallback" */ '../views/OidcCallback.vue')
},
{
path: process.env.BASE_URL + 'profile',
name: 'Profile',
component: () => import('../views/Profile.vue'),
},
{
path: process.env.BASE_URL + 'oidc-silent-renew',
name: 'OidcSilentRenew',
component: () => import('../views/OidcSilentRenew.vue'),
},
{
path: process.env.BASE_URL + 'welcome',
name: 'Welcome',
component: () => import('../views/Welcome.vue'),
},
]
const router = createRouter({
base: '/vue3/',
history: createWebHistory(),
routes
})
router.beforeEach(vuexOidcCreateRouterMiddleware(store, 'oidcStore'))
export default router

Seems I was overlooking. Solution is very simple. Just add isPublic and set it to true under meta in route
const routes = [
...
{
path: process.env.BASE_URL + 'welcome',
name: 'Welcome',
component: () => import('../views/Welcome.vue'),
meta: {
isPublic: true
}
},
...
]

Related

VueJS routing (get rid of lowercase & "/#/"

So I recently wanted to try and learn vuejs, so I used the CLI to create my project and to setup vue-router. Now, with the default vue router configuration the URL's show as /#/ and /#/about. However, in my configuration file I set the paths as / and /About. As I want the URL's to be like that, does anyone know how I can do this?
router > index.js
import { createRouter, createWebHashHistory } from 'vue-router'
const routes = [
{
path: '/',
name: 'Home',
component: () =>
import('../views/Home.vue'),
meta: { title: 'Home', description: 'Foo bar.' }
},
{
path: '/About',
name: 'About',
component: () =>
import('../views/About.vue'),
meta: { title: 'About', description: 'Lorem ipsum.' }
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router
EDIT:
Okay, so I found that the best way to fix this in VueJS v3 is to just switch out createWebHashHistory with createWebHistory, it's literally that simple. After you've switched your imports and the createRouter object, it should all be working fine! 🥳

Accessing to store in the router

I would like to check in my Vuex store whether a user has the 'admin' role before entering the /dashboard route. But I can't properly access data from store.getters.
I use Quasar (Vue.js) and Vuex + Typescript.
In the routes.ts file, on the beforeEnter() function, I can access getters from the store with a console.log(store.myStore.getters). Here I see userInfos inside:
I don't understand why I only get {} and not {...} (Note that if I click on it, I see its contents).
But if I call console.log(store.myStore.getters.userInfos), I don't see the data:
Here is index.ts (router):
import { route } from 'quasar/wrappers'
import VueRouter from 'vue-router'
import { Store } from 'vuex'
import { StateInterface } from '../store'
import routes from './routes'
export default route<Store<StateInterface>>(function ({ Vue }) {
Vue.use(VueRouter)
const Router = new VueRouter({
scrollBehavior: () => ({ x: 0, y: 0 }),
routes,
mode: process.env.VUE_ROUTER_MODE,
base: process.env.VUE_ROUTER_BASE
})
return Router
})
Here is routes.ts (router):
import { RouteConfig } from 'vue-router'
const routes: RouteConfig[] = [
{
path: '/',
component: () => import('layouts/Login.vue'),
children: [
{ path: '', component: () => import('pages/Index.vue') },
{ path: '/inscription', component: () => import('pages/SignUp.vue') },
{ path: '/connexion', component: () => import('pages/SignInPage.vue') }
]
},
{
path: '/main',
component: () => import('layouts/MainLayout.vue'),
children: [
{ path: '', component: () => import('pages/Index.vue') },
{ path: '/dashboard', component: () => import('pages/DashboardB2B.vue'),
beforeEnter: (to, from, next) => {
const store = require('../store')
console.log("before enter")
console.log(store.myStore.getters)
return next();
}, },
{
path: '/ajouter-un-referentiel',
component: () => import('pages/ReferentielMetier.vue')
},
{
path: '/init',
component: () => import('components/bot/BotSkeleton.vue')
}
]
},
{
path: '/bot',
component: () => import('layouts/Bot.vue'),
children: [
{
path: '/ajouter-un-referentiel',
component: () => import('pages/ReferentielMetier.vue')
},
{
path: '/init',
component: () => import('components/bot/BotSkeleton.vue')
}
]
},
// Always leave this as last one,
// but you can also remove it
{
path: '*',
component: () => import('pages/Error404.vue')
}
]
export default routes
And here is index.ts with the store (Vuex):
import Vue from 'vue'
import { store } from 'quasar/wrappers'
import Vuex from 'vuex'
Vue.use(Vuex)
import matching from './modules/matching'
import orga from './modules/organigrame'
import user from './modules/user'
export interface StateInterface {
example: unknown
}
let myStore: any
export default store(function({ Vue }) {
Vue.use(Vuex)
const Store = new Vuex.Store<StateInterface>({
modules: {
matching,
orga,
user
},
// enable strict mode (adds overhead!)
// for dev mode only
strict: !!process.env.DEBUGGING
})
myStore = Store
return Store
})
export {myStore}
EDIT: Looks like my console.log runs before the getters are loaded, because when I check out Vue developer tools, I see everything. How can I check the store if the store itself doesn't load before the beforeEnter function?
please try like this
store.myStore.getters["userInfos"]
I'm having exact issue, even if i use async/await :S
try this
router.beforeEach(async(to, from, next) => {
const userInfo = await store.getters.userInfos;
console.log(userInfo);
});

Vue beforeEach() doesn't redirect to the desired page

I'm trying to redirect/continue to a certain page using vue router, After a user signs up with email and password they should be redirected to another page but the home page just gets reloaded.
I'm not implementing login at the moment, Just the signup part. Every example that I follow works fine in redirecting with just "next()"
import Vue from "vue";
import VueRouter from "vue-router";
import Home from "../views/Home.vue";
import Admin from "../views/Admin.vue";
import Overview from "../views/Overview.vue";
import Products from "../views/Products.vue";
import Orders from "../views/Orders.vue";
import { fb } from "../firebase";
Vue.use(VueRouter);
// The 'name' property hasn't been utilized yet
const routes = [
{
path: "/",
name: "Home",
component: Home
},
{
path: "/admin",
name: "admin",
component: Admin,
// By adding 'requiresAuth' we ensure this route/page and it's children will not be
// accessable by someone who is not authenticated
meta:{ requiresAuth: true },
children:[
{
// Don't put the '/' here
path: "overview",
name: "overview",
component: Overview
},
{
// Don't put the '/' here
path: "products",
name: "products",
component: Products
},
{
// Don't put the '/' here
path: "orders",
name: "orders",
component: Orders
}
]
},
{
path: "/about",
name: "About",
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () =>
import(/* webpackChunkName: "about" */ "../views/About.vue")
}
];
const router = new VueRouter({
mode: "history",
base: process.env.BASE_URL,
routes
});
// ============= This is the method in question ==============
router.beforeEach((to, from, next) => {
const requiresAuth = to.matched.some(x => x.meta.requiresAuth);
const currentUser = fb.auth().currentUser;
// This condition always passes, Even after the user is registered, So it always reloads
// the home page
if (requiresAuth && !currentUser) {
next('/');
// This never runs
} else {
next();
}
});
export default router;

Infinite loop with vue router beforeEach and children paths

When i use beforeEach with children paths debug console show this error: vue-router.esm.js?8c4f:2079 RangeError: Maximum call stack size exceeded
import Vue from 'vue'
import VueRouter from 'vue-router'
import LoginMixin from '#/mixins/LoginMixin.js'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'home',
component: require('#/views/Home.vue').default,
},
{
path: '/login',
name: 'login',
meta: { layout: 'centered' },
component: () => import('#/views/Login.vue'),
},
{
path: '/register',
name: 'register',
meta: { layout: 'centered' },
component: () => import('#/views/Register.vue'),
children: [
{
path: 'user',
component: () => import('#/components/RegisterForm.vue'),
},
{
path: 'company',
component: () => import('#/components/CompanyForm.vue'),
}
]
},
]
//creamos la instancia router modo history(urls amigables)
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
router.beforeEach((to, from, next) => {
if (to.path != '/login' || to.path != '/register/user' && LoginMixin.methods.loginMixinCheckAuth() == false) {
//if not logead and join to other page distinc of login or register redirect to login
next('/login')
}
else {
next()
}
})
I dont know what is bad, the syntaxis is fine and function LoginMixin.methods.loginMixinCheckAuth() is working good (i tested without the function and result is the same).
Hmm at first glance I'd try to make this convoluted if in your beforeEach method simpler. Try to add something like requiresAuth: true to the meta of all your routes that require a logged in user.
In a sense you want something like this in your routes:
// ...
{
path: '/users/:userId(\\d+)/edit/',
name: 'EditUser'
props: true,
meta: {
requiresAuth: true, // <-- add this meta flag against which you check later in beforeEach
},
component: () => import(/* webpackChunkName: "user-edit" */ '#/views/UserEdit.vue'),
},
// ...
And this in your beforeEach:
router.beforeEach((to, from, next) => {
if (to.matched.some((record) => record.meta.requiresAuth)) { // <-- check for requiresAuth here
// assuming your login mixin works
// if I were you I'd store some JWT in localStorage and check that somehow in a vuex getter
if (!LoginMixin.methods.loginMixinCheckAuth()) {
next('/login')
} else {
next()
}
} else {
next()
}
})
To answer this in full would be kinda bulky so go and check out how I did that using meta here and implemented a beforeEach rule here

Redirect to specific url in case of wrong url in vuejs

I have two separate routing files where I am importing the component and defining their routing in each of its file and using it in index.js file. Here are my files code:
//router1.js
import Layout1 from 'Layouts/Panel.vue';
const Users = () => import('Views/Users.vue');
const Reports = () => import('Views/Reports.vue');
export default {
path: '/layout1',
component: Layout1,
redirect:'/layout1/reports',
children:[
{
path: 'reports',
component: Reports,
name:'Reports'
},
{
path: 'users',
component: Users,
name:'Users'
}
]
}
//router2.js
import Layout2 from 'Layout/Panel2';
const Demo1 = () => import('Views/Demo1');
const Demo2 = () => import('Views/Demo2');
export default {
path: '/',
component: Layout2,
redirect:'/demo1',
children:[
{
path: '/demo1',
component: Demo1
},
{
path: '/demo2',
component: Demo2
}
]
}
// index.js
import Vue from 'vue'
import Router from 'vue-router'
import router1 from './router1';
import router2 from './router2';
const NotFound = () => import('Views/NotFound.vue');
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [
router1,
router2,
{
path: '*',
component: NotFound,
name:'NotFound',
},
]
})
Now, I want to redirect to specific url i.e "not-found" in case of wrong URL. In "NotFound" component I am adding below line of code in mounted lifecycle hook which redirects to URL "not-found".
this.$router.replace({ path: 'not-found' });
But if URL is having parameters or query string it will append to it. For e.g- http://localhost:8080/home/not-found
What I want is that it only shows http://localhost:8080/not-found How should I achieve this. Please help. Thanks!
try this in your mounted function. worked on my side.
this.$router.push({path: '/not-found'})