Hello i have a project it contain multiple role (VueJs+Laravel), i'm using laravel as a back-end and vuejs as a front-end,
i have three diffrent role (User,Modirator,Editor).
this is my code in app.js
// VueRouter
import VueRouter from 'vue-router';
import routes from './routes.js';
Vue.use(VueRouter);
var router = new VueRouter({
mode: 'history',
routes
})
this is my routes file:
let routes = [
// General
{ path: '/about', component: require('./components/Home/About.vue').default },
{ path: '/pasword-change', component: require('./components/ChangePassword.vue').default },
// User
{ path: '/User', component: require('./components/User/Dashboard.vue').default },
// Modirator
{ path: '/Modirator', component: require('./components/Modirator/Dashboard.vue').default },
// Editor
{ path: '/Editor', component: require('./components/Editor/Dashboard.vue').default },
// Error
{ path: '*', component: require('./components/Errors/404.vue').default} },
]
export default routes
after login i want to check it in back-end as a ajax request if the role is user use (routes-user.js) elseif is a modirator use (routes-mod.js) else (routes.js).
i dont want to show /user /modirator /editor in client, but i want to check after login and each one show role component in root url /.
thanks for help.
thanks for help....
I tested something similar to your requirement for normal component passing and lazy loading component in Vuex and this works. Below is my code what I am trying to do is have a variable 'unauthorized' and based on which I an loading different component using javascript ternary operator or javascript template string.
import Vue from 'vue'
import Router from 'vue-router'
import Auth from './views/Auth.vue'
import Board from './views/Board.vue'
Vue.use(Router)
let unauthorized = true;
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/auth',
name: 'authenticate',
component: unauthorized ? Auth : Board
},
{
path: '/',
name: 'home',
component: () => import(`./views/${unauthorized ? 'Auth.vue': 'Board.vue'}`)
}
]
})
Specific Solution
As per your requirement, you can store a variable('access-type') in local storage based on whether you log in as 'moderator' or 'user' or 'editor' and then fetch it in router.js file and use template string feature to conditionally change the component path.
Do let me know if you need more help.
You could add meta data to your routes to solve the problem and the check the meta data before you're entering a route:
{ path: '/about', component: require('./components/Home/About.vue').default },
{ path: '/pasword-change', component: require('./components/ChangePassword.vue').default },
// User
{ path: '/User', component: require('./components/User/Dashboard.vue').default, meta: {authorize: ["Admin"]} },
Then add the following method to you router:
router.beforeEach((to, from, next) => {
const { authorize } = to.meta
// get currently logged in user (in my case it's coming from vuex)
const currentUser = store.getters['authentication/user']
if (!currentUser && to.path !== '/login') {
// not logged in so redirect to login page with the return url
return next({ path: '/login', query: { returnUrl: to.path } })
}
if (authorize) {
// check if route is restricted by role
if (authorize.length && !authorize.some(r => currentUser.roles.includes(r))) {
// role not authorised so redirect to home page
return next({ path: '/' })
}
}
next()
})
Related
This question already has an answer here:
Is there a way to accees vue js VueSession in main.js
(1 answer)
Closed 1 year ago.
I use a vue-gapi https://www.npmjs.com/package/vue-gapi in my code to access Google Calendar API. I was successful to install and use this plugin to get data from Calendar API. I now struggle to use router guards.
plugins/vuagapi.js:
import Vue from 'vue';
import VueGapi from 'vue-gapi';
const apiConfig = {
apiKey: '***',
clientId:
'***.apps.googleusercontent.com',
discoveryDocs: [
'https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest',
],
scope: 'https://www.googleapis.com/auth/calendar.readonly',
prompt: 'select_account',
};
Vue.use(VueGapi, apiConfig);
router/index.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from '../views/Home.vue';
import Dashboard from '../views/Dashboard.vue';
import Login from '../views/Login.vue';
import '../plugins/vuegapi.js';
Vue.use(VueRouter);
const routes = [
{
path: '*',
redirect: '/',
},
{
path: '/',
name: 'Home',
component: Home,
},
{
path: '/login',
name: 'Login',
component: Login,
},
{
path: '/dashboard',
name: 'Dashboard',
component: Dashboard,
meta: {
authRequired: true,
},
},
];
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes,
});
router.beforeEach((to, from, next) => {
if (to.matched.some((record) => record.meta.authRequired)) {
if (this.$gapi.currentUser()) {
next();
} else {
alert('You must be logged in to see this page');
next({
path: '/login',
});
}
} else {
next();
}
});
export default router;
I am getting: vue-router.esm.js?8c4f:2314 TypeError: Cannot read property '$gapi' of undefined.
Anyone can point me to right direction? I am able to use this plugin in .vue files but not in another plain .js, suspecting that this $gapi exists only as Vue instakce property/method? As I am beginner I do not know how to import it properly.
if you wanna access Vue instance inside your router use router.app instead of this
change this line :
this.$gapi.currentUser()
to this:
router.app.$gapi.currentUser()
you can read more about Router Instance Properties in : https://router.vuejs.org/api/#router-instance-properties
The Idea
Let me first tell you the idea, user enter "domain.com" user will get redirected to "domain.com/en" where is set by default to the english language, after that user can navigate throughout the website for example to "domain.com/en/about-us/".
My Issue
I can't figure out how to set up the routing for the "domain.com/wrong-page" where is also the global i18n parameter that i'm waiting for or "domain.com/wrong-language/corect-page" so the user can get the appropriate 404 page that i want.
My Set Up
Router file
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import i18n from '../i18n'
Vue.use(VueRouter)
const routes = [
{
path: '/',
redirect: `/${i18n.locale}`
},
{
path: '/:lang',
component: {
render(c) { return c('router-view') }
},
children: [
{
path: '',
name: 'Home',
component: Home
},
{
path: 'about',
name: 'About',
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
},
{
path: '/*',
name: '404',
component: () => import(/* webpackChunkName: "404" */ '../components/404.vue')
}
]
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
Main.js file
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import i18n from './i18n'
import LanguageSwitcher from "#/components/LanguageSwitcher.vue";
import NavigationTopMenu from "./components/NavigationTopMenu.vue";
import Footer from "./components/Footer.vue";
Vue.component('language-switcher', LanguageSwitcher)
Vue.component('navigation-top-menu', NavigationTopMenu)
Vue.component('footer-g', Footer)
Vue.config.productionTip = false
// use beforeEach route guard to set the language
router.beforeEach((to, from, next) => {
// use the language from the routing param or default language
let language = to.params.lang;
if (!language) {
language = 'en'
}
// set the current language for i18n.
i18n.locale = language
next()
})
new Vue({
router,
store,
i18n,
render: h => h(App)
}).$mount('#app')
So, another developer reached out to me, the answer was pretty straight forward we can implement a custom regex for the lang to limit what can be matched with.
:lang
needs to be
:lang(en|fr|es)
another solution is to configure the navigation guard further and redirect to the following error page.
Preface: Very new to Vue.js and Firebase
I have implemented Auth guards on my Vue router file as well as Firebase rules that prevent users from accessing routes manually via url.
While logged in as a test user on my Vue project I manually deleted that user from Firebase. Now I cannot access the login route to change users and nothing is rendering in the browser, no routes are changing etc.
Any idea how I can gain access to my routes again? I'm also not entirely clear what 'requiresGuest' does in terms of authentification
I've included my router.js file below
import Vue from 'vue'
import Router from 'vue-router';
import Home from '../views/Home.vue'
import SalesOrders from '../views/SalesOrders/SalesOrders.vue'
import NewSalesOrder from '../views/SalesOrders/NewSalesOrder.vue'
import ViewSalesOrder from '../views/SalesOrders/ViewSalesOrder.vue'
import Customers from '../views/Customers/Customers.vue'
import NewCustomer from '../views/Customers/NewCustomer.vue'
import EditCustomer from '../views/Customers/EditCustomer.vue'
import ViewCustomer from '../views/Customers/ViewCustomer.vue'
import Login from '../views/Admin/Login.vue'
import Register from '../views/Admin/Register.vue'
import Admin from '../views/Admin/Admin.vue'
import firebase from 'firebase'
Vue.use(Router);
let router = new Router({
routes: [
//ADMIN ROUTES
{
path: '/',
name: 'Dashboard',
component: Home,
meta: {requiresAuth: true}
},
{
path: '/login',
name: 'login',
component: Login,
//Applies a guard so this is accessible to certain people
meta: {requiresGuest: true}
},
{
path: '/register',
name: 'register',
component: Register,
//Applies a guard
meta: {requiresGuest: true}
},
{
path: '/admin',
name: 'admin',
component: Admin,
//Applies a guard
meta: {requiresGuest: true}
},
//SALES ORDERS ROUTES
{
path: '/sales-orders',
name: 'Sales Orders',
component: SalesOrders,
//Requires a login to access
meta: {requiresAuth: true}
},
{
path: '/new-sales-order',
name: 'new-sales-order',
component: NewSalesOrder,
//Requires a login to access
meta: {requiresAuth: true}
},
{
path: '/view-order/:order_id',
name: 'view-order',
component: ViewSalesOrder,
params: true,
//Requires a login to access
meta: {requiresAuth: true}
},
//CUSTOMER ROUTES
{
path: '/customers',
name: 'customers',
component: Customers,
//Requires a login to access
meta: {requiresAuth: true}
},
{
path: '/new-customer',
name: 'new-customer',
component: NewCustomer,
//Requires a login to access
meta: {requiresAuth: true}
},
{
path: '/edit-customer/:customer_id',
name: 'edit-customer',
component: EditCustomer,
//Requires a login to access
meta: {requiresAuth: true}
},
{
path: 'view-customer/:customer_id',
name: 'view-customer',
component: ViewCustomer,
//Requires a login to access
meta: {requiresAuth: true}
},
]
});
// Nav Guard
router.beforeEach((to, from, next) => {
// Check for requiresAuth guard
if (to.matched.some(record => record.meta.requiresAuth)) {
// Check if NO logged user
if (!firebase.auth().currentUser) {
// Go to login
next({
path: '/login',
query: {
redirect: to.fullPath
}
});
} else {
// Proceed to route
next();
}
} else if (to.matched.some(record => record.meta.requiresGuest)) {
// Check if NO logged user
if (firebase.auth().currentUser) {
// Go to login
next({
path: '/sales-orders',
query: {
redirect: to.fullPath
}
});
} else {
// Proceed to route
next();
}
} else {
// Proceed to route
next();
}
});
export default router;
It turns out that Firebase user sessions don't expire when a user is manually deleted from the database.
To resolve this I replaced the App render code in my main.js with the logout function I call when a user clicks the 'logout' button
//This was the original code in main.js
let app;
firebase.auth().onAuthStateChanged(user => {
if(!app){
app = new Vue({
vuetify,
router,
store,
render: h => h(App)
},
console.log(user.email)
).$mount('#app')
}
})
//Replace .onAuthStateChanged with .signOut.then()
firebase.auth().signOut().then(() => {
this.$router.push('/login')
})
I am using vue-router in a nuxt project and when i run npm run generate it generates everything except my pages. I think it has got something to do with the router because before using vue router i had no problems with generating the pages Here is my router:
router.js
import Vue from 'vue'
import Router from "vue-router"
import Home from '../debonkelaer/pages/index.vue'
import actueel from '../debonkelaer/pages/actueel.vue'
import impressies from '../debonkelaer/pages/impressies.vue'
import reglement from '../debonkelaer/pages/reglement.vue'
import reserveren from '../debonkelaer/pages/reserveren.vue'
import tarieven from '../debonkelaer/pages/Tarieven.vue'
import ingelogd from '../debonkelaer/pages/ingelogd.vue'
import firebase from 'firebase/app'
import 'firebase/auth'
Vue.use(Router);
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/actueel',
name: 'Actueel',
component: actueel
},
{
path: '/impressies',
name: 'Impressies',
component: impressies
},
{
path: '/reserveren',
name: 'Reserveren',
component: reserveren
},
{
path: '/tarieven',
name: 'Tarieven',
component: tarieven
},
{
path: '/reglement',
name: 'Reglement',
component: reglement
},
{
path: '/ingelogd',
name: 'Ingelogd',
component: ingelogd,
}
]
const router = new Router({
mode: 'history',
base: '/',
routes
})
export function createRouter() {
return router
};```
If you need any additional code please reply.
When you're working with nuxt.js all routes are automatically generating from all your files in your pagesdirectory. That means you don't need to manually declare every route!
Be sure to check out the official documentation for nuxt.js: Automatic Routing
To check for auth you should use middleware.
If you only need it for one specific route/component, you can use something like the following code in your component's exported function
middleware({ redirect }) {
// If the user is not authenticated
const authenticated = YOUR_AUTH
if (!authenticated) {
return redirect('/login')
}
}
I was trying to work on vue2. and I am facing a strange problem.
I have 4 routes.
/login when user is not logged in they will see this page so they can log in.
/uploads when user login they are redirected to this page.
/train this page for some other work
/documents/collaboration when they use this router it should render train component only but url will be BASE_URL/documents/collaborate
My problem is when I refresh /train page or paste the collaborate url it redirects me to /uploads.
I am not able to know what is wrong with this and why this is happening.
Below is the code for my router.js
import Vue from 'vue'
import Router from 'vue-router'
import LoginPage from './views/Login.vue'
import Uploads from './views/Uploads.vue'
import Train from "./views/Train";
Vue.use(Router)
export const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/login',
name: 'login',
component: LoginPage,
meta: {bodyClass: 'auth-wrapper'}
},
{
path: '/', redirect: '/uploads'
},
{
path: "/uploads",
name: 'Uploads',
component: Uploads,
meta: {bodyClass: 'full-screen', verboseName: 'Data Classifier', icon: '#/assets/img/company5.png'}
},
{
path: "/train",
name: 'Train',
component: Train,
meta: {bodyClass: 'full-screen', verboseName: 'Data Trainer', icon: '#/assets/img/company5.png'}
},
{
path: "/documents/collaborate/:id",
name: "Collaborate",
component: Train,
meta: {bodyClass: 'full-screen', verboseName: 'Data Trainer', icon: '#/assets/img/company5.png'}
}
]
})
router.beforeEach((to, from, next) => {
// redirect to login page if not logged in and trying to access a restricted page
const publicPages = ['/login'];
const authRequired = !publicPages.includes(to.path);
const loggedIn = localStorage.getItem('user-token');
if (authRequired && loggedIn === null) {
return next('/login');
}
if (loggedIn !== null && !authRequired) {
return next('/uploads');
}
next()
})
export default router;
Redirecting to /uploads since the if (loggedIn !== null && !authRequired) {...} condition is true inside route.beforeEach(). Change:
router.beforeEach((to, from, next) => {
...
if (authRequired && loggedIn === null) {
return next('/login');
}
// navigate to to.path() page
next();
})