简体   繁体   中英

Node.js. How restrict page access to unlogged users?

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!

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

http://passportjs.org/docs

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());

you can use authenticate:tur in route provided

.when("/", {
    templateUrl: "pages/login.html", 
    css: ["css/login.css"],
    controller: "loginCtrl",
    authenticate:true,
    controllerAs: "vm",

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM