Vue Router and Laravel Middleware - vue-router

I want to add middleware in vue router, using laravel auth. If auth is checked then it should be allowed to open url otherwise retun back.

You can use vue-router Navigation Guards
as per your code i will try to add an example
{
path: '/',
component: HomePage,
beforeEnter: requireAuth
}
My navigation guard will be requireAuth as
function requireAuth(to, from, next) {
if (login) { //you local login check, you can either use vuex or local storage or cookies etc
next()
} else {
next("/login")
}
}

Related

Wait for state update in vuejs router´s beforeEnter

I want to restrict access to certain pages in my vue router. Instead of having the auth logic in each component, I would prefer, for instance, to just have a 'hasUserAccess' check in my child-routes where it´s needed
{
path: 'admin',
name: 'admin',
beforeEnter: hasUserAccess,
component: () => import(/* webpackChunkName: "admin" */ '#/_ui/admin/Admin.vue')
},
...
function hasUserAccess(to, from, next) {
if (myState.user.isAdmin) {
next();
} else {
next({ path: '/noaccess' });
}
}
This works as intended when navigating from another page to the 'admin' page. This does not work when i manually type the /admin url (or pressing f5 while on the admin page) because the user object hasn´t been fetched from the server yet (some other logic is taking care of fetching the user).
The 'beforeEnter' is async, but as far as I know it ain´t possible to 'watch' the user object, or await it, from the router since the router is not a typical vue component.
So how is this common problem normally solved?
Just apply the beforeEach to the router itself. On the router file, you could do this:
router.beforeEach((to, from, next) => {
//in case you need to add more public pages like blog, about, etc
const publicPages = ["/login"];
//check if the "to" path is a public page or not
const authRequired = !publicPages.includes(to.path);
//If the page is auth protected and hasUserAccess is false
if (authRequired && !hasUserAccess) {
//return the user to the login to force the user to login
return next("/login");
}
//The conditional is false, then send the user to the right place
return next();
});
Try to modify this at your convenience, but this is more or less what I do in a situation like yours.

How to perform a SignOut action in Nuxt.js

I'm currently working on porting the following router.beforeEach action that I have for a Vue.js application to something workable within Nuxt.js.
I've had a good trawl of the middleware documentation, but I'm not quite sure what the correct pattern would be to follow.
My callback which runs before every route change in my Vue.js application is as:
// This callback runs before every route change, including on page load.
router.beforeEach(async (to, from, next) => {
// Reset All State When A User Logs Out:
if (to.redirectedFrom === '/sign-out') {
store.dispatch('auth/resetAuthState')
Vue.prototype.authAPI.cleanseLocalStorage()
}
if (to.meta.authenticationRequired) {
if (!store.getters['auth/activeUserIsAuthenticated']) {
next({ name: 'signIn' })
} else {
next()
}
} else {
next()
}
})
I have the following redirect in my Vue router to perform the redirect action:
...
{
path: '/sign-out',
name: 'signOut',
redirect: {
name: 'signIn'
},
meta: {
...{
authenticationRequired: false,
sitemap: {
ignoreRoute: true
}
}
}
},
...
So on a SignOut redirect, I cleanse local storage and do some further state management inside the Vuex store.
However, I have no idea where to start this with Nuxt.js - any ideas would be greatly appreciated.
I suggest that using "Nuxt/auth" for handling your authentication. you can read this docs here:
https://auth.nuxtjs.org/
On a Nuxt.js project I worked on, I created a sign-out.vue page and emptied the localstorage from there, then redirected to the homepage.

Redirected when going from to via navigation guard

I'm trying to protect my Vue components using the Vue router authentication guard.
Case scenario: unauthenticated user lands on home page ("/" route) and he's trying to access "/profile", but that's a private component, so he'll be redirected by the vue router to "/auth/profile", so he'll authenticate and then the Auth component will redirect the user to the "/profile" component, because he got its path in the URL.
That's my guard
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.private)) {
if (!store.getters.getUser) {
//console.log("PRIVATE - NOT authenticated");
next({ path: "/auth" + `${to.path}` });
} else {
//console.log("PRIVATE - authenticated");
next();
}
} else {
//console.log("NOT PRIVATE");
next();
}
});
Everything works as expected, but I get an error and it's annoying
Redirected when going from "/" to "/profile" via a navigation guard.
Somewhere in your code, after being redirected to "/profile", you are being redirected back to "/". And that is what the vue-router is complaining about.
So the problem resides in being redirected multiple times per action.
You'll want to make sure you only have one redirect per navigation action.
problem solved by replacing
next({ name: "Onboarding" });
with
router.push({ path: 'Onboarding' });
Reduce vue-router version to 3.0.7, or
follow code into your app.js or index.js, which one you import vue-router
example:
import Vue from 'vue';
import VueRouter from 'vue-router';
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location, onResolve, onReject) {undefined
if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject)
return originalPush.call(this, location).catch(err => err)
}
Vue.use(VueRouter);
...
#code
This could be because your other component (the one you are pointing to) is redirecting you back.

Vue router allways redirecting to error page

i am trying to setup a redirect when the user is not logged in. But when i do it like in my example the URL changes but i get This page could not be found from nuxt. The code is inside an login.js inside the plugins folder. Then i included this in the nuxt config like this.
plugins: [
'~/plugins/login.js'
],
And here is the actual code for handling redirecting
export default ({ app, store }) => {
app.router.beforeEach((to, from, next) => {
const loggedIn = store.state.account.loggedInAccount
if (!loggedIn) {
if (to.path !== '/redirect') {
next({ path: '/redirect' })
} else {
next()
}
} else {
next()
}
})
}
It looks like the routes are not mounted yet.
You should try to use middleware. It is the conventional way to implement the beforeEach function as mentioned by the official docs. You can read about it from here. If have access to the route object, store object and redirect function inside the middleware, so use redirect to direct to the other routes after validation.

VueRouter, VueJS, and Laravel route guard

I wanted to hide a particular page of my application behind a layer of security (a simple passcode form that will send a request to the server for validation).
Based off the documentation of VueRouter, I figured a beforeEnter would be appropriate. However, I am not entirely sure how one would require a user to access a particular component, and then successfully enter a passcode before being allowed to proceed to this current route.
Does anyone have an example of this? I am having trouble finding anything similar.
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
const routes = [
{ path: '/test/:testURL', component: require('./components/test.vue'),
beforeEnter: (to, from, next) => {
// somehow load another component that has a form
// the form will send a request to Laravel which will apply some middleware
// if the middleware successfully resolves, this current route should go forward.
}
},
];
const router = new VueRouter({
routes,
mode: 'history',
});
const app = new Vue({
router
}).$mount('#app');
Assuming you want to perform authentication only for selected components, you can go with using beforeEnter route guard. Use the following code.
const routes = [
{ path: '/test/:testURL', component: require('./components/test.vue'),
beforeEnter:requireLogin
},
];
function requireLogin(to, from, next) {
if (authenticated) {
next(true);
} else {
next({
path: '/login',
query: {
redirect: to.fullPath
}
})
}
}
Further, you can create a login screen and action in login component to redirect to given redirect parameter after setting authenticated variable to true. I recommend you to maintain authenticated variable in the veux store