Checks in vue-router.beforeEach not restricting access to routes - vue.js

First off, I'm using vuejs 2.0 with webpack, vue-router (in history mode - SPA site), and vuex running on the webpack dev server with hot module loading.
I have about 10 routes mapped out to components. Site is working great, but now I'm adding some token based authentication. I'm using router.beforeEach to perform a token check. If the token is valid, it should let them through. If the token is NOT valid, it should redirect them to the /login page. The problem is that it performs the check and restricts it the first time. But the second attempt allows me to go to the page and display the contents. Every second request seems to process the route properly and redirect to /login. My checkToken() function is always returning false, for testing purposes.
Code:
// Configure Router
const router = new Router({
routes, //routes are configured elsewhere, they work fine so not needed
mode: 'history'
})
router.beforeEach((to, from, next) => {
if(to.path != '/login') {
if(checkToken()) {
logger('There is a token, resume. (' + to.path + ')');
next();
} else {
logger('There is no token, redirect to login. (' + to.path + ')');
next('login');
// next('/login');
// router.push('login');
}
} else {
logger('You\'re on the login page');
}
next();
});
function checkToken() {
return false;
}
Going to the main page ("/"), it redirects to /login as expected. In my console, I have the following 2 entries:
[ 14:36:30.399 ] : There is no token, redirect to login. (/)
[ 14:36:30.399 ] : You're on the login page
Seems to be good. It tried to load "/" and saw there was no token, then redirected to /login where the check sees that we're on the login page and stops.
Now I'll click on my Projects link that will take me to /project. Console output:
[ 14:40:21.322 ] : There is no token, redirect to login. (/project)
Perfect, but the projects page is actually being displayed rather than the login page.
Now I'll click on my Sites link that should take me to /site. Console output:
[ 14:41:50.790 ] : There is no token, redirect to login. (/site) [
14:41:50.792 ] : You're on the login page
Looks good, AND the browser is displaying the site page. This is exactly what I want to see.
Now I'll click on my Requests link that to /request. Console output:
[ 14:44:13.114 ] : There is no token, redirect to login. (/request)
but once again, it's not redirecting. I'm seeing my request page when I should be seeing my login page.
This time, I'll click on my Projects link again (/project) that incorrectly displayed the project page rather than the login page. Console output:
[ 14:47:12.799 ] : There is no token, redirect to login. (/project) [
14:47:12.800 ] : You're on the login page
This time, it redirected my to the /login page, as it should.
It is literally every other link I click that gets redirected appropriately, no matter what order or which link I click. First one redirects, second one doesn't, third one does, fourth doesn't, fifth does, etc...
I've tried next('/login'), next('login'), and router.push('login') and they're all the same result. It knows when it's supposed to redirect, but the redirect only works every other time.
If I do a full request (page refresh, type the address in and press enter), it will always redirect to /login as planned, but I'm trying to do this with an SPA. Anything I'm missing?

Fixed. Oversight on my part.
This is what the router code should have been:
router.beforeEach((to, from, next) => {
if(to.path != '/login') {
if(checkToken()) {
logger('There is a token, resume. (' + to.path + ')');
next();
} else {
logger('There is no token, redirect to login. (' + to.path + ')');
next('login');
}
} else {
logger('You\'re on the login page');
next(); // This is where it should have been
}
// next(); - This is in the wrong place
});
Silly issue with a simple answer, I had my next() in the wrong place so it was always processing it at the end. I am still curious why it ever redirected correctly, though.

Related

Infinite page reload with Vue when redirecting to external authentication URL

Here is what I'd like to implement in my Quasar 2 / Vue 3 application:
User visits any route.
Upon each route change, a backend call is made to check if the user is still authenticated.
If the user is not authenticated, she shall get redirected to the external URL of the authentication provider.
This is my current approach:
router.beforeEach(() => {
api.get('/api/user/current').then((response) => {
userInfoStore.authenticated = true;
userInfoStore.givenName = response.data.givenName;
userInfoStore.fullName = response.data.fullName;
}).catch(() => {
userInfoStore.authenticated = false;
});
if (!userInfoStore.authenticated) {
redirect('http://localhost:8555/oauth2/authorization/keycloak');
}
});
However the following problems occur:
The app constantly reloads itself.
The call to /api/user/current gives NS_BINDING_ABORTED in the browser console.
The console shows Changed to http://localhost:8555/oauth2/authorization/keycloak but gives this error message.
ChunkLoadError: Loading chunk src_layouts_MainLayout_vue failed.

How to redirect to login without add route to history record in vue?

I'm on the page: /foo and click on the button to redirect me to /bar.
But I have beforeEach route event which redirect me to /login. after I do login, I redirect to /bar.
When I on /bar I click on the back button I get to login page. instend I want to get the the last page which is /foo.
How can I do it? is there a way to redirect to login without add route to history record?
router.beforeEach((to, from, next) => {
if (!to.matched.some((record) => record.meta.auth)) { return next(); }
return next({
path: '/login',
});
});
Use replace instead of push when you redirect to the page after login (in the login component).
loginSuccessed() {
this.$router.replace(redirect);
}
Use route.replace insted of router.push. It acts like router.push, the only difference is that it navigates without pushing a new history entry, as its name suggests - it replaces the current entry.
succesffulyLoggedin() {
this.$router.replace({ name: 'dashboard' });
}
read docs here router replace

Redirect to previous url after login in nuxt.js

I basically want to redirect to the previous url when a user has successfully logged in.
I redirect to the login page with the previous url such as /login?redirect=/page1/page2.
And I want when a user authenticates to be redirected back to that url.
I am using the auth-module here: https://auth.nuxtjs.org/
How I login the user.
methods: {
async submit() {
await this.$auth.loginWith('local', {
data: this.form
})
}
}
The only thing that I could found in the docs is this: https://auth.nuxtjs.org/getting-started/options#redirect
which however only redirects to a specific page instead of the previous page in the query.
Any ideas on how to achieve this?
You Can Do This
this.$router.back()
And its go back to the last route.
Programmatic Navigation | Vue Router
https://router.vuejs.org/guide/essentials/navigation.html
Thanks.
There is a fairly detailed discussion in github about Nuxt having an issue with a redirect when you are hitting a protected page directly. The redirect goes to the default page redirect rather than the previously hit page. The correct behavior should be to store the redirect and then proceed to it after authentication (login) with correct credentials.
3 days ago (Apr 14, 2019), MathiasCiarlo submitted a PR on the auth-module repo to fix this. The base reason why the redirect was "lost" has to do with the state of the redirect value not being allowed to be set as a cookie in SSR mode. His code impacts the storage.js file, in particular the setCookie() method. I've included that changed method here just for reference.
setCookie (key, value, options = {}) {
if (!this.options.cookie) {
return
}
const _key = this.options.cookie.prefix + key
const _options = Object.assign({}, this.options.cookie.options, options)
if (isUnset(value)) {
Cookies.remove(_key, _options)
} else {
// Support server set cookies
if (process.server) {
this.ctx.res.setHeader('Set-Cookie', [_key + '=' + value])
} else {
Cookies.set(_key, value, _options)
}
}
return value
}
I've personally just altered my npm myself, but you could probably fork the repo and use that forked npm for the time being. Or you could wait until the PR is merged into the mainline of the auth-module repo.

Authentication with Angular 5

I have a login page and I need to go to my home page after successful login. That login functionality login to a ldap server and send a response whether the authentication is success or not. I don't want that to keep in localstorage since this app has only two pages. login and home. When login success it should redirect to home page, if not it should redirect to again to the login page.
And please the console.log in the browser, "inside auth guard true" prints thousands times..
The only code I have in my app.component.html is <router-outlet></router-outlet>
In the canActivate(), all you need to do is return true or false. When you are redirecting it to home from inside the function you are entering into an infinite loop.
This is because on redirecting to home the canActivate() gets called and its expects a boolean return value. If the value is false, it won't load the component.
canActivate() {
if (this.authService.loggedIn) {
console.log('Inside Auth Gaurd');
return true;
}
console.log('auth gaurd false path');
return false;
}
For more detail on canActivate() refer this

Aurelia Redirection to the anonymous page or any other page with default access-token without going to login page....?

I developing a demo app which is having a login page., By default I am loading to that default page. But For some pages I want to go with the URL directly redirect to that page. But aurelia default loading to the login page. How can I redirect to the anonymous URL or some URL with my token directly without going to Login page.
Can anyone explain me or give a sample ?
You can use canActivate()
canActivate(params, routeConfig, navigationInstruction) {
//some check for token in params
if (hasToken) {
return new Redirect(`/someroute/${token}`);
}
// proceed and load login page
}
or you can use different routes like
{ route: 'login', moduleId: './pages/login'},
{ route: 'login/token/:token', moduleId: './pages/anonym'},