I am using vue.js router in order to re-direct users to the home page (via "next") if they try to access certain pages which require authentication without having a cookie (which is set upon authentication). I would like to pass a variable to the home page within the next route (i.e. next({ name: 'Home' }, variable)), but I am not finding the proper syntax to implement this.
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth) {
var cookie = document.cookie
if (cookie === '') {
next({ name: 'Home' })
} else {
next()
}
}
})
Thank you. J
Related
I have qr codes that have been published with an old url. I need to redirect that old url to a new external url. I have just revamped this project by incorporating Nuxtjs. I have tried using the redirect middleware, but no success. Can somebody help me?
I want my old url, 'example.io/guestbooklet/1' to redirect to 'https://dashboard.example.io/guestbooklet/1'
middleware/redirects.js
export default function(req, res, next) {
const redirects = [
{
from: "/guestbooklet/:property_id",
to: "https://dashboard.example.io/guestbooklet/:property_id"
}
]
const redirect = redirects.find((r) => r.from === req.url)
console.log('Redirecting', redirect)
if (redirect) {
res.writeHead(301, { Location: redirect.to })
res.end()
} else {
next()
}
}
nuxt.config.js
serverMiddleware: [
'~/middleware/redirects.js'
],
I'm currently practicing VueJs and making some sample apps. i'm making a very simple app that is basically just a login page where users will put their credentials and access their profile. However I can't think of a way to restrict view to the profile section if the user isn't logged (i.e that they try to access by manually changing the url to /profile)
The app is pretty barebones, it's just using JS and bootstrap.
Is there a way to immediately redirect users back to the login screen if they're not logged and try to access the profile page?
You can use https://router.vuejs.org/guide/advanced/navigation-guards.html beforeEach to check if the current user is logged or not and do what you need to do :).
your routes:
...
{
path:'/profile',
meta:{guest:false},
component:ProfileComponent
},
...
example :
router.beforeEach((to, from, next) => {
if (!to.meta.guest) {
// check if use already logged
// if true then go to home
return next({path:'/'}); // '/' is home page for example
// else then continue to next()
}
return next();
});
You can use also beforeEnter param if you have only few routes which should be protected.
routes.js
import {ifAuthenticated} from "../middleware/authentication";
{
path: '/test',
name: 'Test',
component: Test,
beforeEnter: ifAuthenticated
},
authentication.js
import store from '../../store'
export const ifAuthenticated = (to, from, next) => {
store.dispatch('User/getUser')
.then(() => {
next()
})
.catch(() => {
next({ name: 'Login', query: { redirect_to: to.fullPath } })
})
}
Example with usage of vuex.
I am currently trying to only show pages, if the user is logged in. The problem I face is that requireAuth() seems to get called endless amount of times.
The code is use is:
// Routes
const routes = [
{
path: '/',
component: Dashboard,
beforeEnter: (to, from, next) => {
requireAuth(to, from, next);
},
children: [
{
path: '',
name: 'dashboard',
component: DashboardIndex
}, {
path: '*',
name: '404',
component: NotFound
}
]
}, {
path: '/login',
component: Login,
name: 'login',
},
];
function requireAuth (to, from, next) {
if (!localStorage.token) {
console.log('testing');
next({
path: '/login',
query: { redirect: to.fullPath }
})
} else {
next()
}
}
// Routing logic
let router = new VueRouter({
routes: routes,
mode: 'hash'
});
testing is output ~1000 times before I receive the error:
[vue-router] uncaught error during route navigation:
warn # app.js
app.js RangeError: Maximum call stack size exceeded
How can I make sure that /login is redirected to if !localStorage.token?
I faced this same issue as the respective error's source all boils down to next() function which is the required to navigate to the path which has to.path as value. If you'll use router.push or router.replace then possibility is to get called endless amount of times as callstack max error displays. So use simply next() and let router API do cumbersome work
I have done this type of thing, but in different manner. I handled all logic in main.js file. and routes.js file contains -
var routes = [{
path:'/login',
component: Login
},
{
path:'/',
component: dashboard
}]
Now I have controlled all type of validation in main.js file using vue-router API as taking help from this - https://router.vuejs.org/en/api/route-object.html
So now main.js would contain -
const checkToken = () => {
if(localStorage.getItem('token') == (null || undefined) ){
console.log('token is not there : ' + localStorage.getItem('token'));
return false;
}
else{
return true
}
}
//then Use `router.push('/login')` as
router.beforeEach((to, from, next) => {
if(to.path == '/') {
if(checkToken()) {
console.log('There is a token, resume. (' + to.path + ')' + 'localstorage token ' + localStorage.getItem("token"));
next();
} else {
console.log('There is no token, redirect to login. (' + to.path + ')');
router.push('/login');
}
}
So you can structure like this as control all the things in main.js and leave route.js outta everything
If you don't have a localStorage token present you are redirecting a user to /login.
Because this is also a a Vue route, your requireAuth logic will run again(because it runs for every route). Meaning you have just created a infinite loop where a user will constantly be redirected to /login even if a user is already on that page.
To stop this simply do not redirect to /login when you already are on /login.
I will leave that part to you but it shouldn't be that hard if you understand what is going on.
I am trying to add SAML authentication using passport-saml for my application. I am using Angular for routing. On loading of the homepage, I check for a user through a GET request to my node server "/auth" to check req.user, if it's true, I send back logged in user data; if false, I send back an error message. I have data binding on this user data response so in the event of no user data, I still show "Log in" button.
On click of the "Log in" button, I perform a redirect to the node server "/login". This does passport.authenticate function which runs and then ties in with "/assert" when it's complete to perform a redirect.** It is at this point I am running into a problem.** My redirect always goes to "/" because I am performing a redirect and using angular routing so I dont know how to store this route say "/myPage1" or "/myPage2". NOTE: I do not want to always send back to "/myPage1", I want to be able to "Login" from any view in the SPA.
Am I going about this in the wrong way? Is this a limitation of using Angular routing?
Angular
$scope.login = function () {
window.location.href = 'http://example.com/login';
};
function getCreds() {
$http.get('http://example.com/auth', { withCredentials: true })
.then(function (response) {
$scope.creds = response.data;
});
}
Node.js
app.get('/login', passport.authenticate('saml', { failureRedirect: '/login' }));
app.post("/assert", passport.authenticate('saml', { failureRedirect: '/login' }), function (req, res) {
// console.log('session' + JSON.stringify(req.session));
// console.log("original url " + req.session.originalUrl);
if (req.session.originalUrl) {
res.redirect(req.session.originalUrl);
}
else {
res.redirect('/');
}
});
app.get('/auth', function (req, res) {
var authenticated = req.user;
if (authenticated) {
res.send(req.user);
} else {
res.send({statusCode: 401, message: 'User session is not alive'});
}
});
I have found a way to achieve the desired effect.
Before making the "Login" call, I make another api call to "/setSessionRedirectUrl" which passes the current window.location.href from angular to node server for session storage.
app.post('/setSessionRedirectUrl', function (req, res) {
req.session.samlLoginRedirectUrl = req.body.redirectUrl;
res.send();
});
Then when the assert function is being run after login, it is looking for the req.session.samlLoginRedirectUrl to redirect to. It works!
I am trying to write code for my route that if the session.user_id is undefined redirect back to the home page. For some reason the redirect doesnt execute and the mysql condition is fired and it crashes the server because the session.user_id is undefined and it cant load the game without that data.
Is there a way to use a universal redirect on all routes that if session is not available redirect back to login?
router.get('/game', function(req,res) {
console.log(req.session.user_id);
if (req.session.user_id === "undefined") {
res.redirect('/');
}else {
var condition = 'userId = ' + req.session.user_id;
projectX.allGameData(condition, function(data){
var hbsObject = {heroes : data, logged_in: req.session.logged_in, isUser: req.session.isUser, isAdmin: req.session.isAdmin}
res.render('game', hbsObject);
});
};
});
You should either use:
if (req.session.user_id === undefined)
OR
if ( typeof req.session.user_id === "undefined")
Apart from that, it's usually better to have a middleware function that checks for user session. This way, you can just insert the call to this middleware in all your routes, which require the user to be logged in:
router.get('/game', checkUserSession, function(req,res) {
// Your code here
});
function checkUserSession( req, res, next )
{
if( req.session.user_id )
{
next();
}
else
{
res.redirect('/homepage');
}
}//checkUserSession()
I assume the value is undefined, and not "undefined" (which is a string containing the word "undefined"):
if (req.session.user_id === undefined) {
...
}
//Inject authHandler as middleware
router.get('/my/route/', authHandler, (req, res) => {
//secure point, the authHandle went thru
});
function authHandler(req, res, next) {
if (req.session.user_id) {
next();
}
res.redirect('/login/');
}
Add a function to handle the Auth check and then inject is a middleware to your router.