Reputation: 124
Im trying to make a filter with tokens to restrict page access to unlogged users on node.js 0.10, I using a middleware like this:
app.all( "/product/*" , handler);
// won't match /product <-- Important
// will match /product/cool
// will match /product/foov
From this page: Express.js Middleware Tutorial, whitout result, all my pages except login page, are private, and I want that, if an unlogged user try to go to some private page, he is redirected to login page. The token work perfect on login. That is my code:
My tree of components
server - routes - usuario.js server.js pages - privadas -inicio.html -mapa.html -menu.html - login.html
server.js
var app = express();
...
var requiereLogin = require('./server/routes/usuario');
app.all('/privadas/*', requiereLogin);
...
usuario.js
var express = require('express');
var router = express.Router();
...
router.use(function(req,res,next){
console.log("filter...");
var token = req.headers['auth-token'];
jwt.verify(token, process.env.SECRET, function(err, decoded){
if (err){
res.redirect('/login');
} else {
req.user_id = decoded.IDU;
next();
}
})
});
app.config
app.config(function($routeProvider){
$routeProvider
.when("/", {
templateUrl: "pages/login.html",
css: ["css/login.css"],
controller: "loginCtrl",
controllerAs: "vm"
})
.when("/privadas/mapa", {
templateUrl: "pages/privadas/mapa.html",
controller: "mapCtrl",
controllerAs: "vm"
})
.when("/privadas/inicio", {
templateUrl: "pages/privadas/inicio.html",
controller: "inicioCtrl",
controllerAs: "vm"
})
.otherwise({redirectTo:'/'});
});
Any idea? Thanks!
Upvotes: 1
Views: 4714
Reputation: 124
Finally, I have used this tutorial based on the response of Vignesh:
Creating authentication based routes in Angular JS
Which explains step by step very well! But here, its my code:
rutas.js
app.config(function($routeProvider){
$routeProvider
.when("/", {
templateUrl: "pages/login.html",
css: ["client/styles/css/login.css"],
controller: "loginCtrl",
controllerAs: "vm"
})
.when("/mapa", {
templateUrl: "pages/privadas/mapa.html",
controller: "mapCtrl",
controllerAs: "vm",
authenticated: true
})
.when("/inicio", {
templateUrl: "pages/privadas/inicio.html",
controller: "inicioCtrl",
controllerAs: "vm",
authenticated: true
})
.otherwise({redirectTo:'/'});
});
app.run(['$rootScope', '$location', 'authFactory', function ($rootScope, $location, authFactory){
$rootScope.$on('$routeChangeStart', function(event, next, current){
console.log(event);
console.log(current);
console.log(next);
//Si la siguiente ruta es privada, el usuario debe tener un token
if(next.$$route.authenticated){
console.log("auth");
var userAuth = authFactory.getAccessToken();
if(!userAuth){
//Redireccionamos a la pagina de login
$location.path('/');
}
}
})
}]);
factorias.js
app.factory('authFactory', [function() {
var authFactory = {};
authFactory.setAccessToken = function(accessToken){
authFactory.authToken = accessToken;
};
authFactory.getAccessToken = function(){
return authFactory.authToken;
};
return authFactory;
}]);
And my loginController:
app.controller("loginCtrl", function($scope, $http, $location, userService, authFactory){
vm = this;
vm.funciones = {
logearse : function(usuario){
$http.post('/api/user/login', usuario)
.then(function(response){ //Si el login es bueno, obtendremos al usuario, sin la contraseña, y su token.
console.log(response);
//userService es el servicio junto con localStorage, que mantendrá el token y el usuario de la sesión.
userService.token = response.data.token;
userService.user = response.data.userData;
localStorage.setItem('token', JSON.stringify(userService.token));
localStorage.setItem('user', JSON.stringify(userService.user));
authFactory.setAccessToken(response.data.token);
//Redireccionamos a la pagina de inicio
$location.path('/inicio');
}, function(err){
console.error(err);
vm.error = err.data;
})
}
}
});
I hope it will serve more people!
Upvotes: 0
Reputation: 1222
you can use authenticate:tur in route provided
.when("/", {
templateUrl: "pages/login.html",
css: ["css/login.css"],
controller: "loginCtrl",
authenticate:true,
controllerAs: "vm",
Upvotes: 1
Reputation: 2836
I would advice passport.js. Its a bit to explain and walk through so I added a link to the doc and some basic examples to help you get started. It will allow you to store user information and uses that to restrict access to a given route
Your routes.js
app.all('/privadas/*',AuthHelpers.loginRequired, requiereLogin);
function loginRequired(req, res, next) {
if (!req.session.passport || !req.session.passport.user)
return res.status(401).json({status: 'Please log in'});
return next();
}
Your passport.js
const passport = require('passport');
var models = require('../server/models/index');
passport.serializeUser((user, done) => {
var session={
user.user,
}
done(null, session);
});
passport.deserializeUser((user, done) => {
models.users.findOne({
where: {
user: user.user
}
}).then(function(user) {
done(null, user);
}).catch(function (err) {
done(err, null);
});
});
module.exports = passport;
In App.js
const passport = require('./auth/local');
app.use(passport.passport.initialize());
app.use(passport.passport.session());
Upvotes: 2